[APM32E1] 按键扫描实现

[复制链接]
35|3
SpiritSong 发表于 2026-9-14 22:37 | 显示全部楼层 |阅读模式
[i=s] 本帖最后由 SpiritSong 于 2026-9-14 22:38 编辑 [/i]

按键扫描实现

​ ​ 按键状态机是嵌入式系统中替代阻塞式延时消抖的工业级方案,核心是将按键的物理交互过程抽象为离散的有限状态集合,所有状态迁移由确定性条件驱动,全程不阻塞CPU主流程,可同时支持短按、长按、双击等复杂交互逻辑。

核心设计优势

  • 完全摒弃 HAL_Delay()阻塞消抖,不影响系统其他外设的实时响应
  • 单定时器资源即可驱动任意数量按键,无需为每个按键分配独立外部中断
  • 状态逻辑完全解耦,新增双击、连发等交互模式无需重构核心代码
  • 彻底规避机械按键5~20ms弹跳引发的误触发、重复触发问题

标准状态定义

​ ​ 工业级按键状态机的核心状态共6个,每个状态对应明确的物理语义与工程目的:

状态名称 物理含义 核心作用
KEY_IDLE(空闲) 按键处于稳定释放态,无任何动作 所有状态迁移的起点,确保系统有明确初始态
KEY_DEBOUNCE_DOWN(下降沿消抖) 首次检测到高→低电平跳变,启动消抖验证 过滤按下瞬间的机械弹跳,排除虚假触发
KEY_PRESSED(已确认按下) 消抖完成且按键仍保持低电平 作为短按、长按计时的统一入口
KEY_LONG_PRESSED(长按态) 持续按下时长超过预设阈值(如800ms) 触发长按专属动作,支持周期性连发回调
KEY_DEBOUNCE_UP(上升沿消抖) 首次检测到低→高电平跳变,启动释放消抖 过滤释放瞬间的弹跳,防止假释放误判
KEY_RELEASED(已确认释放) 释放消抖完成且按键稳定高电平 触发短按动作,返回IDLE态等待下一次操作

确定性状态迁移规则

​ ​ 所有状态跳转必须由「当前状态 + 输入事件」的原子条件驱动,无模糊逻辑:

  1. KEY_IDLE → KEY_DEBOUNCE_DOWN:检测到GPIO下降沿,启动20ms消抖计时
  2. KEY_DEBOUNCE_DOWN → KEY_PRESSED:20ms计时结束,期间电平始终为低;若中途电平跳回高则直接退回IDLE
  3. KEY_PRESSED → KEY_LONG_PRESSED:进入PRESSED态后计时超过长按阈值,且按键仍保持按下
  4. KEY_PRESSED → KEY_DEBOUNCE_UP:检测到GPIO上升沿,直接进入释放消抖流程
  5. KEY_LONG_PRESSED → KEY_DEBOUNCE_UP:长按过程中检测到上升沿,进入释放消抖
  6. KEY_DEBOUNCE_UP → KEY_IDLE:20ms释放消抖完成,期间电平始终为高,触发短按事件

工程实现关键细节

  • 采样策略:推荐在SysTick中断中以1ms间隔采样GPIO电平,既完整覆盖5~20ms的抖动窗口,又不会过度占用CPU资源
  • 边沿检测:状态迁移依赖电平跳变的边沿而非绝对电平,需维护上一次采样值与当前值做对比,避免长按期间反复触发事件
  • 时间基准:所有计时基于系统 HAL_GetTick()的时间戳差值计算,不依赖绝对延时,确保时序精度不受主循环负载影响
  • 事件输出:短按、长按事件以标志位形式输出给上层应用,状态机核心逻辑中不直接执行业务动作,保证驱动层与业务层完全解耦

典型硬件适配要点

  • 按键采用内部上拉输入模式,默认未按下时GPIO为高电平,按下时接地为低电平,无需额外外部上拉电阻
  • 若硬件采用下拉接法,只需将电平判断逻辑整体翻转,状态机核心迁移逻辑无需修改
  • 多按键场景下,为每个按键分配独立的状态变量与计时参数,复用同一套状态机处理函数即可,无需重复编写代码
Gfan 发表于 2026-9-15 18:20 | 显示全部楼层
本帖最后由 Gfan 于 2026-9-15 18:22 编辑

整体思路很清晰,用状态机替代阻塞式延时确实更适合多任务场景~
另外如果后续增加双击判断,感觉可以在RELEASED/IDLE之间再保留一个双击等待窗口,这套状态机就比较完整啦
jobszheng 发表于 2026-9-16 09:56 | 显示全部楼层
还是状态机实现靠谱呀
jobszheng 发表于 2026-9-16 09:57 | 显示全部楼层
Gfan 发表于 2026-9-15 18:20
整体思路很清晰,用状态机替代阻塞式延时确实更适合多任务场景~
另外如果后续增加双击判断,感觉可以在RELE ...

我是一直在犹豫这个双击事件。
添加双击事件后,单击就有一个明显的滞后了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

62

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0