打印

【转】GD32中断按下一次却响应两次的解决

[复制链接]
1834|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sunmeat|  楼主 | 2015-3-16 14:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天用按键中断来控制LED灯闪烁。当时有时候经常会出现自己设置的LED闪烁是4下,但是结果却是双倍次数,8下。很不解。源代码如下。
Test3_Led1(void)
{
int K;
for(K=0;K<4;K++)
  {
  GPIO_SetBits(GPIOF,GPIO_Pin_6);
  Mydelay_ms(1000);
  GPIO_ResetBits(GPIOF, GPIO_Pin_6);
  Mydelay_ms(1000);
}


沙发
sunmeat|  楼主 | 2015-3-16 14:39 | 只看该作者
经过研究,发现应该是按键中断没做好,每次都产生2次的中断。这是为什么?
中断服务函数如下:
 void EXTI0_IRQHandler(void)
  {
  //if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
     if (EXTI_GetITStatus( EXTI_Line0)!= RESET)
      {
       EXTI_ClearITPendingBit(EXTI_Line0);  //0
   Led1_Flag++;//做测试用,发现每次都加了2.
   Test3_Led1();
   //EXTI_ClearITPendingBit(EXTI_Line0); //最好放在后面以免造成一清0后,因为按键延时又变1。
      }
  }

使用特权

评论回复
板凳
sunmeat|  楼主 | 2015-3-16 14:41 | 只看该作者
    于是我继续研究。发现原来是这样的。
    每次按键按下是一定有抖动的,抖动应该会有很多下,5下以上是很正常的。按理论上将每次抖动都会长生一个脉冲,也就是一个中断。应该会有不下于5次中断,为什么只响应2次呢。
    其实这个很简单。因为相同管脚每次中断都是相同优先级的,所以即使产生中断也不会响应。只有在第一个中断函数结束之后再来中断才会响应。虽然不响应,但是却会改变中断标志位。一定还有有人问,不是服务函数中把标志位清0了吗?但是由于单片机执行代码速度很快,你请0之后,抖动如果还在那么就还会产生中断号(虽然不响应)。只有在第一次中断结束之后,再次去查看中断号的时候才响应。(注:响应中断首先是直接给总线发命令,不需要单片机查询。因此采用中断比采用查询方式要好的多,减少了CPU的工作量。一旦中断标志位变1,而且没有优先级更高的中断在执行,那么就会响应中断服务函数)现在我们就是每次按键按下以后,虽然中断标志经过清0,但是由于抖动的存在,清0后很有可能再变1。当时不会立刻执行。只有当这个中断服务函数执行完毕才执行。所以每次都有可能调用2次中断服务函数。

使用特权

评论回复
地板
sunmeat|  楼主 | 2015-3-16 14:41 | 只看该作者
    那么我们应该怎么改变呢?
    其实很简单,最好在中断服务函数开头和结尾都把中断标志位清0,那么即使第一次清0后再变1,但是第二次清0是一定会成功的。或者是一次清0,但是在清0之前先延时,确保已经没有抖动。

使用特权

评论回复
5
sunmeat|  楼主 | 2015-3-16 14:42 | 只看该作者
我是选用第一种方案。
代码如下:
void EXTI0_IRQHandler(void)
  {
  //if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
     if (EXTI_GetITStatus( EXTI_Line0)!= RESET)
      {
Mydelay_ms(1000);
       EXTI_ClearITPendingBit(EXTI_Line0);  //0
   Led1_Flag++;//做测试用,发现每次都加了2.
   Test3_Led1();
   //EXTI_ClearITPendingBit(EXTI_Line0); //最好放在后面以免造成一清0后,因为按键延时又变1。
      }
  }

这样即使有抖动每次也只会调用一次中断服务函数。

使用特权

评论回复
6
aozima| | 2015-3-16 15:12 | 只看该作者
竟然在中断IRQ里面delay

使用特权

评论回复
7
sunmeat|  楼主 | 2015-3-16 15:44 | 只看该作者
aozima 发表于 2015-3-16 15:12
竟然在中断IRQ里面delay

我也觉得这个解决办法,有点。。。那么的不靠谱,哈哈,只不过正好碰到这个问题了。

使用特权

评论回复
8
rogerllg| | 2015-3-17 13:26 | 只看该作者
太不靠谱了,当心死机~

使用特权

评论回复
9
niuyaliang| | 2015-3-17 15:36 | 只看该作者
rogerllg 发表于 2015-3-17 13:26
太不靠谱了,当心死机~

是呀,确实不靠谱滴

使用特权

评论回复
10
smilingangel| | 2015-3-17 21:52 | 只看该作者
这个是按键处理上的问题的呗。

使用特权

评论回复
11
angerbird| | 2015-3-22 12:39 | 只看该作者
这个需要对按键程序的做消振处理的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

208

主题

2132

帖子

13

粉丝