stm32外中断多次触发
请问各位大佬一个外中断异常多次触发的问题void EXTI4_IRQHandler()
{
static int x = 0;
delay_ms(10);
if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)//判断按键是否按下
{
EXTI_ClearITPendingBit(EXTI_Line4);
x++;
GPIO_SetBits(GPIOF,GPIO_Pin_8);//设置蜂鸣器发声
delay_ms(200);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
if(x > 1)
{
x = 0;
GPIO_ResetBits(GPIOF,GPIO_Pin_9);//控制灯闪烁
delay_ms(200);
}
GPIO_SetBits(GPIOF,GPIO_Pin_9);
}
}
可是把if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)//判断按键是否按下
换成
if(EXTI_GetITStatus(EXTI_Line4)!=RESET)//判断某个线上的中断是否发生
就会判断出不定时触发了两次,当按键设置成下降沿触发时
EXTI_InitStruct.EXTI_Line = EXTI_Line4;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
中断耗时太久啦,不要再中断里delay 小耳朵1500922649 发表于 2018-10-13 17:46
中断耗时太久啦,不要再中断里delay
改了,不是延时的问题 1、中断函数里放入延时尤其是SysTick延时很容易出现预料不到的冲突的。
2、楼主在进入中断函数后并未立即清中断标志位,而是先来给10ms延时,你可知道在这延时期间按键的抖动已经又触发了多少次外部中断了? wenyangzeng 发表于 2018-10-13 19:31
1、中断函数里放入延时尤其是SysTick延时很容易出现预料不到的冲突的。
2、楼主在进入中断函数后并未立即清 ...
那按键检测的最佳写法应是怎样?还请大佬们明示 ajleo 发表于 2018-10-13 19:38
那按键检测的最佳写法应是怎样?还请大佬们明示
1、清中断标志位
2、禁止EXTI中断
3、点亮LED
4、使能EXTI中断
熄灭LED放在定时中断里执行。 我也是有点懵逼了 wenyangzeng 发表于 2018-10-13 22:05
1、清中断标志位
2、禁止EXTI中断
3、点亮LED
谢谢大佬,也就是说中断里只放标志位了 本帖最后由 toofree 于 2018-10-14 21:37 编辑
检测按键,可以用定时扫描的方法。
给你个鼠标按键按下、弹起,上下双沿检测程序,单次响应,逻辑稍微复杂一点。一般用的都比这简单。
typedef struct
{
unsigned LDOWN:6;
unsigned LDEN :1;
unsigned LDOWN7 :1;
unsigned LUP :6;
unsigned LUEN :1;
unsigned LUP7 :1;
unsigned RDOWN:6;
unsigned RDEN :1;
unsigned RDOWN7 :1;
unsigned RUP :6;
unsigned RUEN :1;
unsigned RUP7 :1;
}Mouse_Key;
extern Mouse_Key MsKey;void Button_Process(void)
{
if(BUTTON_IsPressed(PS2_BUTTON_LEFT) == true)
{
LED_On(LED_D3);
if (MsKey.LDEN == 1)
{
if (MsKey.LDOWN >= 5)
{
MsKey.LDOWN7 = 1;
MsKey.LDEN = 0;
MsKey.LUEN = 1;
}
else
{
MsKey.LDOWN++;
}
}
MsKey.LUP = 0;
}
else
{
LED_Off(LED_D3);
MsKey.LDOWN = 0;
if (MsKey.LUEN == 1)
{
if (MsKey.LUP >= 5)
{
MsKey.LUP7 = 1;
MsKey.LUEN = 0;
MsKey.LDEN = 1;
}
else
{
MsKey.LUP++;
}
}
}
if(BUTTON_IsPressed(PS2_BUTTON_RIGHT) == true)
{
LED_On(LED_D4);
if (MsKey.RDEN == 1)
{
if (MsKey.RDOWN >= 5)
{
MsKey.RDOWN7 = 1;
MsKey.RDEN = 0;
MsKey.RUEN = 1;
}
else
{
MsKey.RDOWN++;
}
}
MsKey.RUP = 0;
}
else
{
LED_Off(LED_D4);
MsKey.RDOWN = 0;
if (MsKey.RUEN == 1)
{
if (MsKey.RUP >= 5)
{
MsKey.RUP7 = 1;
MsKey.RUEN = 0;
MsKey.RDEN = 1;
}
else
{
MsKey.RUP++;
}
}
}
}
MsKey.LDOWN7,MsKey.LUP7,MsKey.RDOWN7, MsKey.RUP7,4个标志位在主程序中处理完才清除。
中断里放标志位只能暂时看看作用,有时硬件冲突和浮空模式IO灵敏过头也会引起无常中断的
页:
[1]