最近做的项目中,关于按键检测调用比较多,因此我也做个适当用法总结。按键状态检测的原理,一般都是通过读相应IO口位是否置位来判断是否按下,并且用延时来消抖以及区分长短按。根据延时的用法,也可以区分为阻塞式和非阻塞式。阻塞式即在延时过程中一直等待到计数值,CPU一直被占用无法去执行别的过程,一般这样是不太合理的设计。所以我们都采用非阻塞式,即用轮询的方式去判断是否延时时间到达,其具体代码如下图:
具体思路就是在第一次检测到按下的情况下,给计时变量赋定时器的计数值,等到大于设定长按时间值后,赋长按状态值给按键状态位。等到松手后,若判断大于消抖时间后赋值短按,然后计时变量初始化,最后返回状态值。
但是这样的写法始终存在一个BUG,即长按结束后,会返回一个长按状态之后还会有个短按状态。在检测函数上,我暂时还没有想到解决方法,不过可以在按键处理时,加上上个状态位一起判断即可。具体代码如下:
void key_handle()
{
static uint32_t key_press_time=0;
static uint32_t key_laststate ;
uint8_t key_nowstate ;
uint8_t handle_flag=0;
key_nowstate=Key_state(&key1_press_time,HOME_KEY_PORT, HOME_KEY_PIN);
if(key_nowstate==KEY_PRESS_SHORT && key_laststate==KEY_PRESS_NULL)
{
handle_flag=1;
}
key_laststate=key_nowstate;
return handle_flag;
}