1、先看一下按键抖动波形
采用锅仔片式按键测量波形。 按键按下与抬起的部分都出现抖动,大致时间10ms左右。 为了防止按键误按或者重复识别,必须要按键消抖处理。 按键消抖有软件方法和硬件方法。
2、硬件方法:
一般增加对地滤波电容,利用电容两端电压不能突变的特性减少抖动杂波,使波形更加规整。
其它的复杂方法如RS触发器威廉希尔官方网站 一般用在没有软件的场合,这里就不做介绍了。
3、软件方法:采用延时检测的方法错开抖动区域。
代码实现1: 这种方法在主循环内轮询按键状态,查询GPIO状态,这种方法最简单,也最常见,但是会增加主循环的负荷,按键按下时会阻塞主循环,降低主循环实时性。 当然主循环的阻塞是否有影响,根据自己情况判断。
while(1)
{
if(KeyGpio == 0)
{
DelayMs(10); //延时10ms
if(KeyGpio == 0)
{
//按键处理代码
}
}
//其它代码
}
代码实现2: 按键GPIO初始化为中断方式,按键按下后产生外部中断事件,进入中断处理函数中,延时消抖,最终调用按键处理函数,或者设置标志位去主循环里调用按键处理函数。 这种在中断中延时消抖的方法不少人使用,其性能还不如第一种方法,缺点很明显,中断中延时会导致低优先级中断阻塞,也导致主循环阻塞,实时性更差。
void KeyGpio_IrqHandler(void)
{
if(KeyGpio == 0)
{
//延时10ms
DelayMs(10);
if(KeyGpio == 0)
{
//按键处理代码
KeyFunction();
}
}
ClearIrqFlag();
}
代码实现3: 按键GPIO初始化为中断方式,按键按下后产生外部中断事件,进入中断处理函数中,不采用延时消抖,而是开启了一个定时器,定时器设定为10ms后产生中断,定时器中断后再次检测按键GPIO,如果仍然是按下状态则调用按键处理函数。 中断中只是开启了定时器,并未阻塞,主循环也没有阻塞,从性能上最优,但是这种方法用到了一个定时器,占用了处理器资源。
void KeyGpio_IrqHandler(void)
{
if(KeyGpio == 0)
{
//未开启定时情况下进入,防止重复开启定时器
if(isTimerStart() == 0)
{
// 设置定时器时间为10ms
InitTimer(10);
// 开启定时器
StartTimer();
}
}
ClearKeyIrqFlag();
}
void Timer_IrqHandler(void)
{
StopTimer();
if(KeyGpio == 0)
{
//按键处理代码
KeyFunction();
}
ClearTimerIrqFlag();
}
以上示例伪代码采用10ms延时,使用时可根据实际情况调整。
全部0条评论
快来发表一下你的评论吧 !