[AT32M412] 【AT-START-M412测评】+ 按钮学习,IO中断,为何下降沿不中断

[复制链接]
476|2
 楼主| gaoyang9992006 发表于 2025-6-13 22:15 | 显示全部楼层 |阅读模式
如果说只跑官方的示例,或者用官方做好的配置文件,那就没啥学习价值了,需要自己动手做一个找不到参考的IO来做中断按钮才行。
开发板上使用的IO是PA0,使用的是下拉电阻,好奇怪,以前我都是看到的上拉电阻,这里用的下拉电阻。
70658684c24d40be15.png
所以我这里切换成我自己画的扩展板上的。我的原理图如下所示,这里使用PB4作为测试IO
32432684c252953261.png
根据我的电路,需要将PB4设置为上拉电阻模式,按钮按下会产生下降沿,我们可以设置下降沿中断。
看到官方做了相关的宏,修改就可以直接配置,但是在中断初始化里又用的是库里面的宏,所以这里我觉得不如直接用库里的,如果你考虑可移植性,那就做彻底啊。
  1. void at32_button_init(void)
  2. {
  3.   gpio_init_type gpio_init_struct;

  4.   /* enable the button clock */
  5.   crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

  6.   /* set default parameter */
  7.   gpio_default_para_init(&gpio_init_struct);

  8.   /* configure button pin as input with pull-up/pull-down */
  9.   gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  10.   gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  11.   gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  12.   gpio_init_struct.gpio_pins = GPIO_PINS_4;
  13.   gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  14.   gpio_init(GPIOB, &gpio_init_struct);
  15. }
接下来实现IO中断的初始化配置
照葫芦画瓢,修改成下降沿
  1. void button_exint_init(void)
  2. {
  3.   exint_init_type exint_init_struct;

  4.   crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
  5.    scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE4);

  6.   exint_default_para_init(&exint_init_struct);
  7.   exint_init_struct.line_enable = TRUE;
  8.   exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
  9.   exint_init_struct.line_select = EXINT_LINE_4;
  10.   exint_init_struct.line_polarity = EXINT_TRIGGER_FALLING_EDGE;
  11.   exint_init(&exint_init_struct);

  12.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  13.   nvic_irq_enable(EXINT4_IRQn, 0, 0);

配套的其他函数也要修改
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  button handler function
  3.   * @param  none
  4.   * @retval none
  5.   */
  6. void button_isr(void)
  7. {
  8.   /* delay 5ms */
  9.   delay_ms(5);

  10.   /* clear interrupt pending bit */
  11.   exint_flag_clear(EXINT_LINE_4);

  12.   /* check input pin state */
  13.   if(SET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_4))
  14.   {
  15.     if(g_speed == SLOW)
  16.       g_speed = FAST;
  17.     else
  18.       g_speed = SLOW;
  19.   }
  20. }

  21. /**
  22.   * @brief  exint0 interrupt handler
  23.   * @param  none
  24.   * @retval none
  25.   */
  26. void EXINT4_IRQHandler(void)
  27. {
  28.   button_isr();
  29. }
注意这里都修改成跟GPIOB4相关的参数
编译烧录,发现没反应。。。
改成上升沿中断,可以工作
  1. void button_exint_init(void)
  2. {
  3.   exint_init_type exint_init_struct;

  4.   crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
  5.   scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE4);

  6.   exint_default_para_init(&exint_init_struct);
  7.   exint_init_struct.line_enable = TRUE;
  8.   exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
  9.   exint_init_struct.line_select = EXINT_LINE_4;
  10.   exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  11.   exint_init(&exint_init_struct);

  12.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  13.   nvic_irq_enable(EXINT4_IRQn, 0, 0);
  14. }
大家看看问题出在哪儿,为何上升沿中断可以,下降沿就不行了?
 楼主| gaoyang9992006 发表于 2025-6-14 06:57 | 显示全部楼层
经过一夜的思考,我好像知道了原因。
在原版的示例,仅仅修改为下降沿中断
60014684cabb392a1f.png
仍然不工作,是不工作吗,还是官方提供的示例的判断方式有问题?
仔细阅读全部代码,发现问题
37053684cabf90a63c.png
在执行动作的时候,它的代码逻辑是选择的是否为高电平。那么板载的板子上是按下后为高电平,上升沿。所以它这么做。
注释掉该行之后,OK了,下降沿的中断动作可以在流水灯上显现出来了。
 楼主| gaoyang9992006 发表于 2025-6-14 07:05 | 显示全部楼层
81388684cae222c50d.png
经过一夜的梦中分析,找到了问题的所在,原来官方的示例中对IO的状态进行了判断后才执行的切换动作。
这或许是为了区分相同中断源的不同IO触发的中断。至此,已经学会了使用该芯片的IO操作方法。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部