大家都知道“Stop Trying to Reinvent the Wheel”不要重复造轮子,但作为嵌入式程序猿每个项目都难免重复造些轮子。这个系(天)列(坑)会挨个介绍一些我日常用到开源组件,前人栽树后人乘凉,缩减项目的开发周期好去摸(填)鱼(坑)。
第一个组件,我重点推荐MultiButton!
按键!几乎每个MCU级别的嵌入式项目都要用到,这是个天天要用的轮子,所以MultiButton这个组件就是我墙裂推荐的。感谢作者0x1abin
MultiButton 是一个小巧简单(一个multi_button.c 一个multi_button.h)易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。
License也非常的友好:MIT license
可以去这里下载到
0x1abin/MultiButton: Button driver for embedded system (github.com)
https://gitee.com/mirrors_0x1abin/MultiButton
使用方法
1. 先申请一个按键结构
struct Button button12. 初始化按键对象,绑定按键的GPIO电平读取接口read_button_pin() ,后一个参数设置有效触发电平
button_init(&button1, read_button_pin, 0, 0);3. 注册按键事件
button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler); button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler); ....
4. 启动按键
button_start(&button1);
5. 设置一个5ms间隔的定时器循环调用后台处理函数
while(1) { ... if(g_TimerTicks >= 5) { g_TimerTicks = 0; button_ticks(); } }
特性
MultiButton 使用C语言实现,基于面向对象方式设计思路,每个按键对象单独用一份数据结构管理:
struct Button { uint16_t ticks; uint8_t repeat: 4; uint8_t event : 4; uint8_t state : 3; uint8_t debounce_cnt : 3; uint8_t active_level : 1; uint8_t button_level : 1; uint8_t button_id; uint8_t (*hal_button_Level)(uint8_t button_id_); BtnCallback cb[number_of_event]; struct Button* next; };
这样每个按键使用单向链表相连,依次进入 button_handler(struct Button* handle) 状态机处理,所以每个按键的状态彼此独立。
按键事件
事件 | 说明 |
PRESS_DOWN | 按键按下,每次按下都触发 |
PRESS_UP | 按键弹起,每次松开都触发 |
PRESS_REPEAT | 重复按下触发,变量repeat计数连击次数 |
SINGLE_CLICK | 单击按键事件 |
DOUBLE_CLICK | 双击按键事件 |
LONG_PRESS_START | 达到长按时间阈值时触发一次 |
LONG_PRESS_HOLD | 长按期间一直触发 |
基于LPC系列的移植参考
以下代码截图基于NXP官方的LPC804开发板。
实际使用的时候,coder还要去看下multi_button.h里的两个宏定义,TICKS_INTERVAL默认是5即5mS,这个与它实例间隔5mS是对应的。DEBOUNCE_TICKS默认是3最大是8,用于按键消抖。长按和短按的时间靠LONG_TICKS和SHORT_TICKS设置或者说优化,这两个宏定义也在multi_button.h中。
全部0条评论
快来发表一下你的评论吧 !