加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

基于状态机和面向对象的思想,设计一个通用的按键检测模块

06/05 09:49
3203
阅读需 7 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

物理按键,在很多嵌入式产品里面应用得非常广泛,很多嵌入式软件工程师在刚刚开始入门的时候,点完灯之后就开始学习按键输入检测。按键输入可以说是继点灯之后,又一经典的嵌入式入门必学内容之一。

在很多嵌入式入门学习的教程里面,按键原理普遍被认为是“很简单”的知识点之一,按键输入检测的原理,无非就是通过CPU不断扫描按键引脚电平状态,或者采用单片机引脚外部中断方式,然后在死循环或者中断服务程序里面处理按键被按下后的逻辑。

然而,在这个“很简单的高低电平检测”的原理背后,通过产品经理给物理按键各个动作赋予的(难以理解的)意义,一个小小的物理按键开始变得复杂起来,这些动作包括:按下、抬起、单击、双击、点动、长按、组合按键。。。等等。

以上这些复杂的按键动作,已经不是一个“简单的高低电平检测”所能描述清楚的了,成熟的单片机按键检测模块,必须能很好地处理以上按键动作,并且具有很高的内聚度,与单片机的底层引脚尽量低耦合,且能提供灵活的应用层调用接口。

采用嵌入式 C 语言面向对象的思想,通过状态机和回调函数的方式,我们来编写一个通用的按键检测模块,以更好地覆盖单片机的物理按键应用场合。
以下是物理按键模块的设计过程。

1、这个通用的物理按键模块,主要是由4个源代码文件组成,key_driver.c和key_driver.h主要是驱动层接口,主要面向不同的单片机引脚适配。key_module.c和key_module.h主要是面向应用层接口,与芯片硬件引脚无关。

2、key_driver.c 和 key_driver.h主要是用来适配不同的单片机GPIO外设的,在key_driver.h里面,声明了一个key_driver_t类型的结构体,主要提供GPIO引脚初始化接口以及引脚电平读取接口,如下图所示。

3、在key_driver.c里面,主要是对初始化接口和引脚电平读取接口的具体实现,比如,引脚初始化接口_init()函数和电平读取接口_read_pin_state(),其具体实现如下图所示。

4、在key_driver.c里面,定义了一个key_driver结构体变量,记住这个变量,很重要,后面会被key_module进行调用,key_driver的具体内容如下图所示。

5、在key_module.h里面,主要是声明了两个重要的结构体,key_t结构体是面向单个按键对象的,主要是包括按键ID以及按键状态枚举,还有一些变量是用来进行按键检测过程的,key_manager_t结构体主要是用来管理多个按键对象的,包括各个按键动作的函数接口,还有按键引脚的驱动程序,如下图所示。

6、按键模块还对外提供了多个外部调用接口,包括模块初始化,按键模块时间更新,按键模块的时基更新,按键模块的按键动作回调函数处理,如下图所示。

7、在key_module.c里面,主要是对以上外部接口的具体实现,比如,key_module_init()主要是对按键模块的各个参数初始化,以及注册按键模块的引脚驱动程序,代码如下图所示。

8、在key_module_update()函数里面,主要是以状态机和回调函数的方式,处理各个按键状态和动作,按键状态有KEY_IDLE、KEY_PRESSED、KEY_RELEASED、KEY_SINGLE_CLICK、KEY_DOUBLE_CLICK、KEY_LONG_PRESS。代码如下图所示。

9、在各个不同的状态里面,通过回调函数的方式,分别对按下、抬起、单击、双击、长按、等按键动作进行处理,限于篇幅,这里只列出部分代码,具体实现请参考具体源码和注释。

10、按键模块需要对其提供系统时基,通常以1毫秒或者10毫秒作为时间基准,key_module_ticks_update()主要是在外部定时器或者外部1毫秒线程中被调用,key_module_set_event_handler()主要是用来设置各个按键状态的回调函数,如下图所示。

11、如何使用key_module?假如项目采用RT-Thread进行调度,在main()函数里面,先创建一个key_module_thread()线程,然后在该线程里面先对按键管理器进行初始化,然后注册各种按键状态的回调函数,最后在while循环里面,更新按键管理器的时基以及状态更新函数,线程主体以1毫秒的间隔进行调度,如下图所示。

12、以上,就是一个通用的单片机按键模块具体设计,通过这个按键检测模块,可以很好地处理各种按键状态事件,并且该按键模块在设计上遵循设备与驱动分离的原则,尽量做到了高内聚低耦合,具体很好的移植性和单片机平台适配性。

13、美中不足的是,这个模块还没有加入组合按键处理,感兴趣的读者,可以下载该模块的源码,对其进行修改和扩展。

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
DSC1001DL5-004.0000 1 Microchip Technology Inc OSC MEMS 4.0000MHZ CMOS SMD
$1.98 查看
SN74LVC1G06DCKT 1 Texas Instruments Single 1.65-V to 5.5-V inverter with open-drain outputs 5-SC70 -40 to 125

ECAD模型

下载ECAD模型
$2.11 查看
APFA3010SEEZGQBDC 1 Kingbright Triple Color LED, Hyr-gre-blu, Water Clear, 2mm, ROHS COMPLIANT, SMD, 4 PIN

ECAD模型

下载ECAD模型
$1.42 查看

相关推荐

电子产业图谱