欢迎来到泰骏兴电子,大家有问题可以直接联系管理员QQ:233619809单片机 QQ群:59194556 各位游客也可以注册玩玩,享受更多权益。温馨提示:本网站仅提供平台学习以及渠道,一切后果自行承担,还望广大用户提高自我意识,请不要轻易相信他人,请不要轻易相信他人,请不要轻易相信他人。为了更好的管理论坛工作,所以现在使用邮箱注册,如果以前的邮箱不能修改的,请联系管理员代为修改

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 36|回复: 0

非常方便的非阻塞独立按键识别程序支持单击长按双击以及多击

[复制链接]
发表于 昨天 16:07 | 显示全部楼层 |阅读模式

  1. /**
  2. * @brief 读取指定按键 GPIO 状态
  3. * @param button_id 按键 ID (0~BUTTON_NUM-1)
  4. * @return BUTTON_PRESSED / BUTTON_RELEASED
  5. * @note 用户根据实际硬件修改 KEY_* 宏或函数
  6. */
  7. static uint8_t read_button_gpio(uint8_t button_id)
  8. {
  9.     switch (button_id) {
  10.         case 0: return KEY_UPPER_IO;     /* 上键 */
  11.         case 1: return KEY_UNDER_IO;     /* 下键 */
  12.         case 2: return KEY_CONFIRM_IO;   /* 确认键 */
  13.         case 3: return KEY_RETURN_IO;    /* 返回键 */
  14.         default: return BUTTON_RELEASED; /* 默认释放状态 */
  15.     }
  16. }
复制代码
以上部分绑定按键,返回状态则是按键按下与非按下状态
  1. /* =====================================================
  2. * 全局回调函数默认实现(弱定义)
  3. * 用户可以在应用层重写这些函数,实现全局按键播报等
  4. * 警告特别需要注意的是,此函数为回调程序,回调程序请不要使用delay_ms()程序,尽可能使用标志位
  5. * ===================================================== */
  6. __weak void Button_Single_Click_Callback(uint8_t button_id) {}
  7. __weak void Button_Double_Click_Callback(uint8_t button_id) {}
  8. __weak void Button_Long_Press_Callback(uint8_t button_id) {}
  9. __weak void Button_Multi_Click_Callback(uint8_t button_id, uint8_t click_count) {}
复制代码

你可以重新定义这些函数。

你唯一需要做的就是在一个定时器中循环调用
  1. void Button_Update_All(void)
复制代码
函数,其他的你都可以不用你管了,接下来就是怎么识别按键,实际上很简单
通过一个函数即可
  1. /* =====================================================
  2. * 获取指定按键事件
  3. * ===================================================== */
  4. /**
  5. * @brief 获取指定按键事件
  6. * @param button_id 按键 ID
  7. * @return ButtonEvent_t 当前事件
  8. * @note 读取后事件会被清零
  9. */
  10. ButtonEvent_t Button_Get_Event(uint8_t button_id)
复制代码
我们通过这个函数接口就可以获取到按键是什么状态了,按键的状态可以有

  1. /* =========================================================
  2. * 按键事件类型定义
  3. * ========================================================= */
  4. typedef enum {
  5.     BUTTON_EVENT_NONE = 0,   /* 无事件 */
  6.     BUTTON_EVENT_SINGLE,     /* 单击 */
  7.     BUTTON_EVENT_DOUBLE,     /* 双击 */
  8.     BUTTON_EVENT_LONG,       /* 长按 */
  9.     BUTTON_EVENT_MULTI       /* 多击(次数 > 2) */
  10. } ButtonEvent_t;
复制代码
例如我们使用按键单击
  1.    if(Button_Get_Event(KEY_UNDER_IO)==BUTTON_EVENT_SINGLE)
  2.         {


  3.         }
复制代码
我们这里的:KEY_UNDER_ID就是在前面定义的按键ID,这个ID就是read_button_gpio中的哪一个按键,例如这里的是KEY_UNDER_ID=0


如果要想实现长按,那就将按键单击改成长按事件即可。

如果一个按键要想识别短按,长按,以及双击怎么办,实际上上也很简单,只需要使用:ButtonEvent_t定义一个按键状态标志就可以, 然后判断这个标志使用if()else if()结构进行嵌套判断即可
同时还通过一个按键按下次数识别程序
  1. /**
  2. * @brief 获取最近一次多击按下的次数
  3. * @param button_id 按键 ID(0 ~ BUTTON_NUM-1)
  4. * @return 多击次数(>2 才有效)
  5. * @note 仅在 BUTTON_EVENT_MULTI 后调用有效
  6. */
  7. uint8_t Button_Get_Click_Count(uint8_t button_id);
复制代码
可以在按键标志位:BUTTON_EVENT_MULTI后再进行一次按键按下次数识别









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|泰骏兴电子科技有限公司 ( 粤ICP备2023060260号-1 ) 单片机爱好者

GMT+8, 2026-5-31 00:55

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表