# MultiButton
## 简介
MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。
MultiButton的作者是0x1abin, github地址: https://github.com/0x1abin/MultiButton.
## 使用方法
1.先申请一个按键结构
```c
struct Button button1;
```
2.初始化按键对象,绑定按键的GPIO电平读取接口**read_button_pin()** ,后一个参数设置有效触发电平
```c
button_init(&button1, read_button_pin, 0);
```
3.注册按键事件
```c
button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler);
button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler);
...
```
4.启动按键
```c
button_start(&button1);
```
5.设置一个5ms间隔的定时器循环调用后台处理函数
```c
while(1) {
...
if(timer_ticks == 5) {
timer_ticks = 0;
button_ticks();
}
}
```
## 特性
MultiButton 使用C语言实现,基于面向对象方式设计思路,每个按键对象单独用一份数据结构管理:
```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 (*hal_button_Level)(void);
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 | 长按期间一直触发
## Examples
```c
#include "button.h"
struct Button btn1;
uint8_t read_button1_GPIO()
{
return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
}
void BTN1_PRESS_DOWN_Handler(void* btn)
{
//do something...
}
void BTN1_PRESS_UP_Handler(void* btn)
{
//do something...
}
int main()
{
button_init(&btn1, read_button1_GPIO, 0);
button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);
button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler);
button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler);
button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler);
button_attach(&btn1, LONG_PRESS_START, BTN1_LONG_PRESS_START_Handler);
button_attach(&btn2, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler);
button_start(&btn1);
//make the timer invoking the button_ticks() interval 5ms.
//This function is implemented by yourself.
__timer_start(button_ticks, 0, 5);
while(1)
{}
}
...
```
## 状态图
![states.png](states.png)
嵌入式STM32好用的按键处理程序-MultiButton源码
需积分: 0 12 浏览量
更新于2023-03-07
1
收藏 96KB RAR 举报
在嵌入式系统开发中,STM32微控制器因其丰富的外设接口、高性能以及低功耗特性而被广泛应用。在实际应用中,按键是常见的人机交互方式之一,因此掌握有效的按键处理程序至关重要。本篇将详细介绍基于状态机实现的嵌入式STM32按键处理程序——MultiButton源码。
我们要理解STM32中的按键处理通常涉及硬件中断和轮询两种方式。硬件中断方式可以实时响应按键事件,但可能会增加处理器负担;轮询方式则相对较简单,但响应速度可能较慢。MultiButton库则提供了一种平衡两者的方法,它利用状态机机制来优化按键检测,提高了处理效率和用户体验。
状态机是一种用于描述系统或过程行为的模型,它通过定义不同的状态以及状态间的转换来管理事件。在MultiButton中,每个按键对应一个独立的状态机,主要有以下几个状态:
1. **IDLE**(空闲):无按键按下时的状态,系统在此状态下监测按键是否被按下。
2. **PRESSED**(按下):当检测到按键被按下时,状态机进入此状态。
3. **DEBOUNCE**(去抖动):由于机械按键存在抖动,状态机在此状态进行去抖处理,确保按键按下是稳定的。
4. **RELEASED**(释放):按键释放后,状态机进入此状态。
5. **CLICK**(单击):如果按键在短时间内快速释放,状态机认为发生了一个单击事件。
6. **LONG_PRESS**(长按):若按键持续按下达到预设时间,状态机判断为长按事件。
MultiButton库的实现原理如下:
- **初始化**:在程序开始时,对每个按键进行初始化,设置其状态机初始状态为IDLE,并配置相应的中断或定时器来检测按键变化。
- **中断服务函数**:当按键引脚的中断触发时,更新相应按键的状态机,可能使其从IDLE变为PRESSED或从RELEASED变为PRESSED。
- **状态机更新**:在主循环中,检查每个按键的状态机,根据当前状态和输入信号进行状态转换。例如,如果按键在PRESSED状态下保持一段时间未改变,则进入DEBOUNCE状态;在DEBOUNCE状态下,如果检测到按键释放,则进入RELEASED状态。
- **事件处理**:当状态机触发单击或长按事件时,库会调用预设的回调函数,通知用户应用程序进行相应的处理。
在MultiButton-master压缩包中,包含了源代码、示例项目和相关的文档,帮助开发者快速理解和使用这个库。开发者可以通过阅读源码了解状态机的具体实现细节,也可以参考示例项目快速将MultiButton集成到自己的项目中。
MultiButton库是针对STM32嵌入式系统的高效按键处理解决方案,它利用状态机模型优化了按键的检测和处理,既降低了硬件中断的开销,又提供了可靠的事件检测,适用于各种需要按键交互的场景。对于希望提升嵌入式项目用户体验的开发者来说,这是一个非常有价值的工具。
cf.y
- 粉丝: 267
- 资源: 7
最新资源
- 某名企年度培训计划.doc
- 年度培训计划表.doc
- 年度培训预算制订的几个困惑.doc
- 年度培训计划制定五步曲.doc
- 培训制度.doc
- 企业集团员工培训计划(2016年度)(DOC 5页).doc
- 企业如何做培训规划.doc
- 企业年度培训计划制定实务.doc
- 新人入职15天强化培训计划(DOC 7页).doc
- 傻瓜式开展年度培训规划工作.doc
- 宇辉2015培训方案(管理人员)(DOC 8页).doc
- 逸阳服饰2015年培训规划.doc
- 2024年中国经济复苏与出口新动能研究报告
- 通过python实现一个堆排序示例代码.zip
- 02助代-集团消费品经营理念(ppt 15)).PPT
- 03助代-营业人员专业准则.PPT