嵌入式中,经常使用按键作为人机交互的接口,典型的按键电路如下所示:
在实际使用过程中,由于误触及按键的机械特性,按键按下或松开时的输出的波形上会存在抖动,一般可以通过增加滤波电容C1进行处理。但是在实际产品应用中,尤其是在在一些低功耗、低成本要求的应用场景中,会取消滤波电容C1并增大电阻R1的阻值,按键按下或送开时的抖动会增大。
一、硬件消抖
1、IC硬件消抖
IC硬件滤波,一般依赖与使用硬件平台的GPIO实现。部分MCU的GPIO实现支持硬件滤波功能:一般采用高于待采样信号频率的时钟,对待采样信号进行多次采样实现。采样周期越长,对应的产生误判的概率越下。存在硬件滤波时,软件可以直接获取相对可靠的结果。
2、板级硬件消抖
板级硬件滤波,通常是在电路中与按键并联接入一个滤波电容,利用电容的充放电延时进行消抖。需要设计好充放电常数,时间常数太大按键不灵敏,连续按键可能无法正确识别按键信号;时间常数太小,达不到消抖的效果。这种方法对于软件实现来说最简单,可以认为结果是可靠的,但增加了硬件成本,在一些低成本产品无法采用。
二、软件消抖
1、单次延时消抖
根据按键的机械特性,按键在按下或松开时的抖动时长一般为10ms,所以可以以10ms为间隔对按键进行两次判断获取按键实际状态(按下或松开)。若检测到按键按下则延时一定时间(如10ms),再次获取按键状态,若按键仍为按下,则按键按下,否则可认为是扰动。
bool keyRead(void)
{
if (KEY == 1)
{
DelayMs(10);
if (KEY == 1)
{
return true;
}
}
return false;
}
该方法在保护电阻R1阻值较小时效果较好,不依赖滤波电容也可以获取准确的按键状态。
2、多次延时消抖
软件滤波的另一种方法,以较小的间隔对按键多次采样,若采样结果一致则为正确的按键状态。比如以1ms的间隔对按键连续采样8次。
bool keyRead(void)
{
uint8_t i;
uint8_t key = 0;
for (i = 0; i < 8; i++)
{
key |= (KEY & 0x1) << i;
}
if (key == 0xff)
{
return true;
}
return false;
}
在保护电阻R1较大时(低功耗产品),该方法感觉效果较好些。