三行又四行,简单实现长按双击识别
前段时间里,论坛曾经研究过一个三行代码实现按键识别的帖子,近来研究双击和长按的时候,心血来潮研究了一下。成功实现了一种非常简单的双击和长按识别,其中,按键识别占用四行,双击和长按的逻辑占用四行。首先,我们分析一下双击和长按的逻辑,长按即是按下按键后超过了某一个时间,双击则是在单击后的某一段时间内,再次按下按键。所以,如果追求响应速度的话,单击和双击必然是识别冲突的,这里建议只保留双击功能,否则第一下肯定会识别为单击,处理不好甚至会造成逻辑混乱。在上面的逻辑里面,我们不仅仅需要获取到按键按下的边沿,还需要获取到按键抬起的边沿。所以,我们需要对代码做一些小小的改动。代码部分:先贴一下代码:val = Get_Key();
down = val & (val ^ old);
up = old & (val ^ old);
old = val;这里,我们通过get_key()函数获取了本次按下的键值(这里是矩阵键盘和独立按键都可以,只需要返回对应的数字就可以了)然后,我们使用(val^old)进行边沿检测,如果两次一次为0一次为有效数字,则会返回一个有效数字。然后通过val&(val^old)对当前值进行比较,如果当前值为val(从0到val),则判断为上升沿,如果上次为有效数字,即从val到0,则为下降沿,实现代码为:old&(val^old)
这就完成了上升沿和下降沿的识别,那么长按和双击此时也变得很简单了。先贴一下代码:u32 l_key = 0, d_key = 0;
if (down == 9)
{
l_key = time;
if (time - d_key < 200)
Mode = Tmp_Mode;
}
if (up == 9)
{
if (time - l_key > 500)
Mode = UART_Mode;
else
d_key = time;
}
这里,down是按下边沿的键值,up是抬起边沿的键值,time为u32大小的1ms自加值。当按键按下的时候,保存一次当前的时间戳。抬起的时候,判断第一次按下的时间戳和当前是的差值,如果大于500ms,则判定为长按。此时保存一次抬起时间戳,如果有第二次按下时,发现距离上次抬起时间小于200ms(时间较短),则可以判断为双击。如果想要拓展为多个按键的双击和长按,可以对l_key和d_key拓展为数组形式,对每个按键进行分别存储。双击和长按实现,核心代码只需要四行即可,并且继承了三行代码按键识别的优点,判断边沿,自带消抖。
这里放一下完整的代码程序,适合大部分的官方开发板,使用P32作为按键,每次长按取反P20口,每次双击取反P21口
没有完整代码看不懂 zhang32568 发表于 2024-5-16 16:55
没有完整代码看不懂
稍等我整理一下发个完整的代码 王昱顺 发表于 2024-5-16 18:02
稍等我整理一下发个完整的代码
谢谢 共同学习。三行经典代码的帖子是我发的。双击和长按没有研究透 贴下完整的代码 烧录研究下 这种如果要检测多个输入信号的状态该怎么处理,比如上升沿,下降沿啥的 希望楼主加上双击和长按 牛啊,{:5_332:}学习了 期待完整、完美代码分享{:4_197:} 组合键 研究研究{:4_197:}