深入解析:全功能按键非阻塞式

0.实物接线图


1.全功能按键非阻塞式建立

简单来说就是实现按键的单击、双击、长按等效果

定时器中断的固定时间一般可取20~40ms,这样可以天然的过滤掉按键的抖动


2.标志位定义


3.置标志位的时刻


4.状态转移图

状态转移图是状态机思路最重要的部分,画好了状态转移图,代码就能很顺利的完成

红字:状态名称;绿字:触发状态转移的条件;蓝字:对应位置需要执行的程序功能

首先定义一个全局变量或者静态变量,来表示状态码


5.全功能按键非阻塞式搭建代码

第一步:复制定时器实现非阻塞式程序代码,命名为全功能按键非阻塞式实现

第二步:改造Key.c代码

Key.h头文件声明

第三步:主函数调用

全功能按键非阻塞式搭建完整代码


6.按键接法

7.移植流程

Key.h中

确定KEY_COUNT按键个数

定义每个按键的名称和索引号

Key.c中

实现Key_Init按键引脚初始化的代码

实现Key_GetState读取按键引脚状态的代码

main.c中

自行实现一个1ms定时中断,并在中断里调用Key_Tick函数

调用Key_Check函数,若指定按键的指定事件发生,则返回1,否则返回0

8.注意事项

在一轮主循环中,只能检查一次指定按键的指定事件(KEY_HOLD除外),若确实需要检查多次,则可先调用一次Key_Check函数并用变量存储返回值,后续多次判断此变量即可

错误,因为在Key_Check函数中已经清除标志位了,在次检测是检测不到的

加一个变量存储即可

双击事件的存在,使得单击事件响应有一些延迟,若程序中没有使用到双击,则可将双击时间阈值改为0,这样可以消除单击事件的延迟

按键产生了事件,对应的标志位就会一直置1,直到检查了此事件,才会自动清0,这在模式切换时可能会导致误动作

例如:模式1中没有检查过某个标志位,但是按下过按键,此标志位已经置1,随后切换为模式2,开始检查此标志位,那么一旦进入模式2,此标志位的动作就会立刻响应

解决办法:在切换模式时,统一将所有的Key_Flag清0,避免上一个模式的按键标志位对这个模式产生影响

posted @ 2026-01-30 21:55  yangykaifa  阅读(3)  评论(0)    收藏  举报