javnson 发表于 2022-5-17 10:47

[GD32F310评测]中断测试和GPIO使用

<p cid="n300" mdtype="paragraph">在本节我们将就上一次实现的按键功能进行改进,并提供一个按键响应函数,目前只是实现一个呼吸灯点亮和熄灭的切换功能,在之后将会起到其他的作用。</p>

<p cid="n301" mdtype="paragraph">本节最核心的目标在于分析GD32芯片的中断机制,GPIO的使用和寄存器分析,并将代码进行整理。</p>

<h3 cid="n302" mdtype="heading">中断配置</h3>

<p cid="n303" mdtype="paragraph">中断的设置对应使用指南的3.10节。301这款芯片能够支持24个独立配置的中断。其中给出了中断配置的函数概要,编程测或过程中可以通过查阅此手册来确定函数的调用。</p>

<p cid="n304" mdtype="paragraph">但是在具体应用中需要关注用户手册中6.3节中的中断向量表。在本项目中采用的中断配置和端口配置函数如下:</p>

<pre cid="n305" lang="C++" mdtype="fences" spellcheck="false">
&nbsp;void peripheral_init()
&nbsp;{
&nbsp;    // RCU:
&nbsp;    rcu_periph_clock_enable(RCU_GPIOA); &nbsp;// GPIO A
&nbsp;    rcu_periph_clock_enable(RCU_CFGCMP); // CFGCMP clock
&nbsp;   
&nbsp;    // System tick
&nbsp;    systick_config();
&nbsp;   
&nbsp;    // GPIO config
&nbsp;    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_0); // Input Key
&nbsp;    gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1); &nbsp;// Output Key
&nbsp;    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_1);
&nbsp;    gpio_bit_reset(GPIOA, GPIO_PIN_1);
&nbsp;   
&nbsp;    // NVIC
&nbsp;    nvic_irq_enable(EXTI0_1_IRQn, 2U, 0U); // GPIO A0 -&gt; EXTI 0
&nbsp;    syscfg_exti_line_config(EXTI_SOURCE_GPIOA, EXTI_SOURCE_PIN0); // GPIO A0 Interrupt enable
&nbsp;    exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
&nbsp;    exti_interrupt_flag_clear(EXTI_0);
&nbsp;   
&nbsp;}</pre>

<p cid="n306" mdtype="paragraph">接下来我们要在主函数中实现一个非常简单粗暴的PWM灯光渐变,这个例程将会一直保持到后面的各个例程中,作为判定是否出现系统死机的直观判定。</p>

<h3 cid="n307" mdtype="heading">主循环中的PWM呼吸灯</h3>

<p cid="n308" mdtype="paragraph">下面给出PWM灯的主要逻辑</p>

<pre cid="n309" lang="C++" mdtype="fences" spellcheck="false">
&nbsp;      static uint8_t pwmset;
&nbsp;      static uint16_t time;
&nbsp;      static uint8_t timeflag;
&nbsp;      static uint8_t timecount;
&nbsp;      static uint32_t tick_old;
&nbsp;      if ((tick - tick_old &gt;= 1)) // 减少不要的循环
&nbsp;      {
&nbsp;            tick_old = tick;
&nbsp;​
&nbsp;            if (timeflag == 0)
&nbsp;            {
&nbsp;                time++;
&nbsp;                if (time &gt;= 1600) timeflag = 1;
&nbsp;            }
&nbsp;            else
&nbsp;            {
&nbsp;                time--;
&nbsp;                if (time == 0) timeflag = 0;
&nbsp;            }
&nbsp;​
&nbsp;            // duty
&nbsp;            pwmset = time / 80;
&nbsp;​
&nbsp;            // generate PWM which width is 20ms
&nbsp;            if (timecount &gt; 20) timecount = 0;
&nbsp;            else timecount++;
&nbsp;​
&nbsp;            if (timecount &gt;= pwmset) gpio_bit_set(GPIOA, GPIO_PIN_1);
&nbsp;            else gpio_bit_reset(GPIOA, GPIO_PIN_1);
&nbsp;      }</pre>

<p cid="n310" mdtype="paragraph">以上这段代码需要在主循环中调用。接下来定义系统滴答时钟,在文件<code>gd32f3x0_it.c</code>中定义</p>

<pre cid="n311" lang="C++" mdtype="fences" spellcheck="false">
&nbsp;uint32_t tick = 0;
&nbsp;void SysTick_Handler(void)
&nbsp;{
&nbsp; &nbsp; &nbsp;delay_decrement();
&nbsp;      tick += 1;
&nbsp;}</pre>

<p cid="n312" mdtype="paragraph">在<code>main.c</code>中需要给出外部变量的声明</p>

<pre cid="n313" lang="C++" mdtype="fences" spellcheck="false">
&nbsp;extern uint32_t tick;</pre>

lugl4313820 发表于 2022-5-17 12:02

呼吸灯,看起来舒服一点,谢谢分享。。

javnson 发表于 2022-5-22 08:42

lugl4313820 发表于 2022-5-17 12:02
呼吸灯,看起来舒服一点,谢谢分享。。

<p>单独灯亮灯灭真的程序跑飞了死机了自己都不知道<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/hug.gif" width="60" /></p>
页: [1]
查看完整版本: [GD32F310评测]中断测试和GPIO使用