定时器处理按键抖动

一、按键的抖动
1.按键的定义和原因

按键抖动是由于‌机械按键在闭合和断开时,由于触点的弹性作用,会产生一系列的抖动现象。这种抖动对于人类来说几乎感觉不到,但对‌单片机来说,却是一个可以感应到的过程,且处理时间较长,通常在毫秒级。‌

2.按键抖动的影响

按键抖动会导致单片机在处理按键信号时出现误判,即一次按键操作可能被错误地识别为多次操作,从而导致误处理。例如,按键一次按下或释放可能被误认为是多次操作,进而引起系统的逻辑错误。 

3.按键消抖的方法

为了消除按键抖动的影响,可以采取以下几种方法:

1)软件消抖:通过程序实现,主要有两种方法:延迟法和计数法。延迟法是在检测到按键状态变化后,延时一段时间再进行确认;计数法则是在检测到按键状态变化后,连续检测一定次数,如果状态没有发生变化,则确认为有效状态。‌

2)硬件消抖:通过电路实现,有多种方法。例如,应用‌施密特电路的回差特性配合积分电路实现按键消抖,或者应用‌锁存器的保持功能实现开关消抖。‌

3)综合消抖:结合软件和硬件两种方法来实现,以达到更好的消抖效果。‌

下面介绍软件消抖。

二、按键的软件消抖

一般有两种方法,1.延时几十毫秒之后再读。2.按键按下,延时10ms,再判断是否有中断,直到没中断。第 1 种方法太耗时,违背“中断要尽快处理”的原则,你的系统会很卡。在 GPIO 中断中并不立刻记录按键值,而是修改定时器超时时间,10ms 后 再处理。如果 10ms 内又发生了 GPIO 中断,那就认为是抖动,这时再次修改超时时间为 10ms。只有 10ms 之内再无 GPIO 中断发生,那么定时器的函数才会被调用。在定时器函数中记录按键值。

/* 定义一个软件定时器的结构体 */  
struct soft_timer {  
    uint32_t timeout;    // 定时器超时时间  
    void * args;         // 传递给定时器函数的参数  
    void (*func)(void *); // 定时器超时后调用的函数  
};  
  
/* 全局变量 */  
int g_key_cnt = 0; // 按键计数  
  
/* 定义一个软件定时器实例,初始超时时间设置为最大(~0),无参数,超时函数为key_timeout_func */  
struct soft_timer key_timer = {~0, NULL, key_timeout_func};  
  
/* 定时器超时函数,每次调用时增加按键计数,并重置定时器超时时间为最大 */  
void key_timeout_func(void *args)  
{  
    g_key_cnt++;  
    key_timer.timeout = ~0;  
}  
  
/* 设置定时器超时时间 */  
void mod_timer(struct soft_timer *pTimer, uint32_t timeout)  
{  
    pTimer->timeout = HAL_GetTick() + timeout; // HAL_GetTick()获取当前系统时间,加上超时时间作为新的超时时间  
}  
  
/* 检查定时器是否超时,如果超时则调用超时函数 */  
void check_timer(void)  
{  
    if (key_timer.timeout <= HAL_GetTick())  
    {  
        key_timer.func(key_timer.args);  
    }  
}  
  
/* 外部中断回调函数,当检测到特定引脚(GPIO_PIN_14)的中断时,重置定时器超时时间 */  
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  
{  
    if (GPIO_Pin == GPIO_PIN_14)  
    {          
        mod_timer(&key_timer, 10); // 设置定时器超时时间为当前时间加10(单位取决于HAL_GetTick()的实现)  
    }  
}

总结,这段代码的主要用途是在特定的GPIO引脚(是GPIO_PIN_14,按需更改引脚)发生外部中断时,启动一个10单位时间的定时器。如果在定时器超时之前该引脚再次发生中断,则重置定时器。定时器超时后,会调用key_timeout_func函数,该函数会增加g_key_cnt变量的值,表示按键事件被记录,经试验,能满足按键防抖处理要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值