STM32F103按键中断消抖问题求教!

[复制链接]
查看11 | 回复9 | 2021-1-27 06:20:33 | 显示全部楼层 |阅读模式
最近在学习STM32,想实现4个按键的中断控制,现在有几个问题,想问下。
1:按键利用中断方式控制是不是就能避免抖动?
我认为是不行的,所以想在外部中断处理函数中加入延时起到消抖的目的,但是加入延时函数后,中断函数就无法运行,在网上搜索后我发现是不能在中断函数中加入延时的,延时函数如下:
voiddelay_ms(u32time)
{
delaytime=time;
while(delaytime!=0);
}
...
voidSysTick_Handler(void)
{
delaytime--;
}
2:那么现在有几个解决方案:
一:在中断函数中仅做状态标志传递,在主函数中用switch根据不同的状态值运行具体的程序,这个办法可以,但是我还是不清楚能不能做到消抖。
二:我在网上看到有人修改内核中的这个函数:
static__INLINEuint32_tSysTick_Config(uint32_tticks)
{
if(ticks>SysTick_LOAD_RELOAD_Msk)return(1);/*Reloadvalueimpossible*/
SysTick->LOAD=(ticks&SysTick_LOAD_RELOAD_Msk)-1;/*setreloadregister*/
NVIC_SetPriority(SysTick_IRQn,(1VAL=0;/*LoadtheSysTickCounterValue*/
SysTick->CTRL=SysTick_CTRL_CLKSOURCE_Msk|
SysTick_CTRL_TICKINT_Msk|
SysTick_CTRL_ENABLE_Msk;/*EnableSysTickIRQandSysTickTimer*/
return(0);/*Functionsuccessful*/
}
里面的NVIC_SetPriority(SysTick_IRQn,(1 -->
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
没这个复杂
不管什么中断,里面都不要加延时
如果用外部中断的话,你在IO线上并个电容就可以去抖动了
一般按键用定时器扫描,如果被拉低或拉高就计数,反之清初计数,计数到一定值就认为有按键
voidtimer0(void)
{
if(io_key==0)keycnt++;elsekeycnt=0
if(keycnt==5)key=1;//连续5次都采集到就认为有按键
}
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
dceacho给出的方法非常实用。我补充一下,普通人按下或者抬起按键时的抖动时间大多数在20ms以内,楼主可以用示波器抓一下波形看看,然后根据这个时间确定定时器的扫描时间和计数次数。
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
一般都是4-10ms扫描程序,2次扫到同样的内容,才会进行按键解码
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
学到了,一起学习一起进步。
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
弄个10ms的延时就行
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
的确,定时器扫描,然后处理按键操作。设置好检测时间,然后定时器中不停调用。实际应用也很少会出现抖动
staticvoidKeyStatusGet(volatileKEY*pKey,u8power)
{
//pKey->hardStatus=pKey->keyHardStatus(pKey);
//if(pKey->keyHardStatus(pKey)==KEY_UP)
if((pKey->GPIOx->IDR&pKey->GPIO_Pin)!=(uint32_t)Bit_RESET)
{
pKey->status=KEY_STATUS_UP;
pKey->pressCnt=0;
}
else
{
pKey->pressCnt+=KEY_SCAN_TIME;
if(pKey->pressCnt>=KEY_NORMAL_DOWN_TIME&&pKey->status==KEY_STATUS_UP)
{
//if(power)
//;//pKey->status=KEY_STATUS_DOWN_POWER;
//else
pKey->status=KEY_STATUS_DOWN_NORMAL;
}
elseif(pKey->pressCnt>=KEY_LONG_DOWN_TIME)
{
pKey->pressCnt=KEY_LONG_DOWN_TIME;
if(pKey->status!=KEY_STATUS_DOWN_POWER&&power)
pKey->status=KEY_STATUS_DOWN_POWER;
elseif(KEY_STATUS_DOWN_LONG!=pKey->status&&pKey->status!=KEY_STATUS_DOWN_POWER)
pKey->status=KEY_STATUS_DOWN_LONG;
//if(power==0&&KEY_STATUS_DOWN_LONG!=pKey->status)
//pKey->status=KEY_STATUS_DOWN_LONG;
}
}
}
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
不错不错学习些学习学
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
多次扫描是常用方式,其实中断也可以去除掉一些抖动,毕竟中断处理前的抖动都被无视了
回复

使用道具 举报

千问 | 2021-1-27 06:20:33 | 显示全部楼层
中断优先级大于systick,时钟得不到更新,死循环在中断函数里
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行