1、前言

嵌入式(单片机)裸机 C 语言开发 + 按键扫描(模块分层/非阻塞式)文章后,原来的按键识别基本能满足大部分需求,但是对于双击和多击等多样化的功能需求并不能满足,因此对整个按键动作识别模块进行了架构调整,此次调整后接口使用更加便捷。


2、介绍

重构后的按键动作识别模块特点:

  • 移植方便,只需要实现硬件 IO 初始化和 IO 状态读取即可
  • 支持多种按键(有些按键不一定是一个 IO 对应按键, 如矩形按键、红外远程遥控按键等)的输入
  • 丰富的接口实现,通过这些接口能及时处理按键操作,同时可以实现单击、双击、多击、短按和长按等多种要求的功能
  • 代码量少,且代码注释丰富,风格统一,便于阅读和使用

相对于之前的实现方式有以下变化:

  1. 移除每个按键的配置信息设置,简化代码
  2. 移除按键异步读取(读取之前保存起来各个状态,读取时依次i返回)的功能
  3. 移除多个按键状态的变化,只留下三种状态:无按下、按下和松开
  4. 增加获取按键按下和松开的时间获取、按键一定时间内的触发次数,根据上述三种状态可实现单击、双击、多击、短按和长按等多种要求的功能

整体来说,使得按键动作识别的各种要求更快速的实现。


3、示例代码

源文件部分代码:

/**
* @brief 获取按键单击次数
*
* @note 调用该函数时不能有关于按键动作的限制条件
* @param[in] eKey 指定按键, 取值为 @reg IoKeyType_e
* @param[in] time 每次单击的间隔时间
* @retval 单击次数.
*/
uint8_t KEY_GetClickCnt(IoKeyType_e eKey, uint16_t time)
{
if (eKey >= IO_KEY_MAX_NUM)
{
return 0;
} /* 连续单击后等间隔时间再进行回调通知, 目的在松开按键后再次触发得到单击次数 */
if (sg_tKeyManage[eKey].eKeyAction == KEY_ACTION_LOSSEN)
{
sg_tKeyManage[eKey].refreshNotifyTic = time;
} if (sg_tKeyManage[eKey].eKeyActionBak != KEY_ACTION_PRESS && sg_tKeyManage[eKey].eKeyAction == KEY_ACTION_PRESS)
{
sg_tKeyManage[eKey].refreshNotifyTic = 0; if (sg_tKeyManage[eKey].clickCnt < 0xFF)
{
sg_tKeyManage[eKey].clickCnt++;
}
} if (sg_tKeyManage[eKey].eKeyAction == KEY_ACTION_NO_PRESS && sg_tKeyManage[eKey].uiLossenTic >= time)
{
uint8_t cnt = sg_tKeyManage[eKey].clickCnt; sg_tKeyManage[eKey].clickCnt = 0;
return cnt;
} return 0;
}

头文件部分代码:

/* Exported types ----------------------------------------------------------------------------------------------------*/
typedef enum
{
KEY_ACTION_NO_PRESS = 0, /*!< 没有按下 */
KEY_ACTION_PRESS, /*!< 持续按下 */
KEY_ACTION_LOSSEN /*!< 按下松开 */
} KeyAction_e; typedef void (*KeyFunCB)(IoKeyType_e, KeyAction_e); /* Exported constants ------------------------------------------------------------------------------------------------*/
/* Exported macro ----------------------------------------------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------------------------------------------------*/ extern void KEY_Init(void); extern void KEY_Register(IoKeyType_e eKey, KeyFunCB pfnKeyFun);
extern void KEY_UnRegister(IoKeyType_e eKey); extern void KEY_SetNotifyTime(IoKeyType_e eKey, uint16_t time); extern uint8_t KEY_GetClickCnt(IoKeyType_e eKey, uint16_t time);
extern uint16_t KEY_GetPressTime(IoKeyType_e eKey);
extern uint16_t KEY_GetLossenTime(IoKeyType_e eKey); extern void KEY_Scan(uint16_t cycleTime);

4、代码获取

下载链接点击:MCU 按键动作识别模块

轻量级按键动作识别模块(C语言)的更多相关文章

  1. 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)

    本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...

  2. AVR单片机教程——按键动作

    上一篇教程中我们学习了如何读取按键状态.而按键的动作,比如单击,至少需要两个状态才能判定,长按.双击的判定更加复杂.今天我们来学习如何使用库函数判断按键单击,以及其实现原理. 我们要实现的是:当一个按 ...

  3. RGBD动作识别的多视图层融合模型

    摘要 基于视觉的动作识别在实践中遇到了不同的挑战,包括从任何角度识别主题,实时处理数据以及在现实环境中提供隐私.甚至识别基于配置文件的人类动作(基于视觉的动作识别的一个子集),在计算机视觉中也是一个巨 ...

  4. 微软手写识别模块sdk及delphi接口例子

    http://download.csdn.net/download/coolstar1204/2008061 微软手写识别模块sdk及delphi接口例子

  5. Action4D:人群和杂物中的在线动作识别:CVPR209论文阅读

    Action4D:人群和杂物中的在线动作识别:CVPR209论文阅读 Action4D: Online Action Recognition in the Crowd and Clutter 论文链接 ...

  6. opencv实现人脸识别(五) 运用tkinter进行GUI绘制 整合人脸识别模块

    因为之前学习过tkinter库,所以在学习了人脸识别模块的编写后, 打算绘制一个简单的GUI来应用人脸识别功能. 主界面如下所示: 签到打开在点开后直接进行人脸识别,如果成功则自动关闭视频窗口. 录入 ...

  7. Quirc二维码识别模块

    背景 师兄要用这个参加集赛,但是说自己C语言不太行,花了一个多小时帮他分析了一下(虽然自己也不太行). 对应模块的GitHub地址:https://github.com/dlbeer/quirc. 记 ...

  8. python中的future,你见过可以使用未来版本模块的语言吗?

    import xxx from yy.xxx import xx from yy.xxx import xx as x python最常见的导包导模块语句 yy为包名,包就是文件夹,模块就是xxx.p ...

  9. pycharm导入自己写的包的时候,不能识别模块的解决办法

    今天用写selenium脚本的时候导入自己统计目录下的模块时,出错,明明存在但是报错说模块不存在,找了半天终于找到解决方案,顺便记录一下吧 pycharm不会将当前文件目录自动加入自己的sourse_ ...

  10. opencv实现人脸识别(四) 人脸识别模块

    到这一步就是进行人脸识别了. 流程图: 代码: import cv2 def recognize(cam): recognizer = cv2.face.LBPHFaceRecognizer_crea ...

随机推荐

  1. SCA技术进阶系列(一):SBOM应用实践初探

    现代软件都是组装的而非纯自研.随着开源组件在数字化应用中的使用比例越来越高,混源开发已成为当前业内主流开发方式.开源组件的引入虽然加快了软件开发效率,但同时将开源安全问题引入了整个软件供应链.软件组成 ...

  2. Linux下安装neo4j

    Linux下安装neo4j 一.JDK安装 参照https://www.cnblogs.com/yclh/p/14849228.html 中jdk1.8的安装 二.下载neo4j 下载地址:https ...

  3. vue 基于axios封装request接口请求——request.js文件

    https://blog.csdn.net/m0_67393593/article/details/123266577?utm_medium=distribute.pc_relevant.none-t ...

  4. scrollIntoView页面滑动特效

    点击左侧的菜单,页面平滑滚动:

  5. vue判断用户在页面停留时间是否超时

    需求 当用户停留超过15分钟后,用户提交订单,提示用户超时并重新加载页面 代码 data () { return { // 超时定时器 overTimer: null, // 是否超时 isOvert ...

  6. Linux 系统安全加固经验总结

    本文为博主原创,转载请注明出处: 目录  1. 禁止root密码登录 2. linux 用户密钥复杂度及有效期设置 3. 检查sudo权限 4.关闭ftp 5.设置文件的属主并指定读写执行权限 6.管 ...

  7. PR 调整时间线宽度

    1.问题 这里的宽度太小,不好进行下一步的调整 2.解决方法 方法一 按下=可以放宽 按下-(=左边的那个键)可以缩小宽度 方法二 拖动下方的滑动条即可 方法三 按住ALT+滚轮,即可调节

  8. Shell-全局变量-export

  9. Linux-服务管理-service-checkconfig

  10. [转帖]ipv6相关内核参数配置的优化实践

    https://zhuanlan.zhihu.com/p/605217713 调整ARP缓存大小 这个参数通常需要在高负载的访问服务器上增加.比如繁忙的网络(或网关/防火墙 Linux 服务器),再比 ...