# MultiButton **Repository Path**: maoxiaomeng/MultiButton ## Basic Information - **Project Name**: MultiButton - **Description**: 简介 MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 28 - **Created**: 2022-07-20 - **Last Updated**: 2022-07-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MultiButton ## 简介 MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。 ## 使用方法 1.先申请一个按键结构 ``` struct Button button1; ``` 2.初始化按键库 ``` button_init(); ``` 3.注册按键事件 ``` button_attach(&button1, read_button_pin, Callback_DOUBLE_Click_Handler, SINGLE_CLICK|DOUBLE_CLICK); ... ``` 4.启动按键 ``` button_start(&button1); /*按键在button_attach()初始化之后,默认是启动的,在重新启动前无需调用*/ ``` 5.设置一个5ms间隔的定时器循环调用后台处理函数 ``` while(1) { ... if(timer_ticks == 5) { timer_ticks = 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 button_level : 1; uint8_t (*hal_button_Level)(void); BtnCallback cb; struct Button* next; }; ``` 这样每个按键使用单向链表相连,依次进入 button_handler(struct Button* handle) 状态机处理,所以每个按键的状态彼此独立。 ## 按键事件 事件 | 值 | 说明 ---|---|--- BTN_UNPRESS | 0x00 | 按键未按下 BTN_PRESSED | 0x01 | 按键被按下 PRESS_DOWN | 0x02 | 按键按下,每次按下都触发 PRESS_UP | 0x04 | 按键弹起,每次松开都触发 PRESS_REPEAT | 0x08 | 重复按下触发,变量repeat计数连击次数 SINGLE_CLICK | 0x10 | 单击按键事件 DOUBLE_CLICK | 0x20 | 双击按键事件 LONG_RRESS_START | 0x40 | 达到长按时间阈值时触发一次 LONG_PRESS_HOLD | 0x80 | 长按期间一直触发 ## Examples ``` #include "button.h" struct Button btn1; int read_button1_GPIO() { /* 按键被按下返回 BTN_PRESSED,否则返回 BTN_UNPRESS */ if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin)) return BTN_UNPRESS; else return BTN_PRESSED; } int main() { /* 初始化按键库 */ button_init(); /* 注册按键 */ button_attach(&btn1, read_button1_GPIO, BTN1_PRESS_Handler, PRESS_DOWN|PRESS_UP|PRESS_REPEAT|SINGLE_CLICK); /* 默认启动,这里无需调用 */ //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) {} } /* 按键响应函数 */ void BTN1_PRESS_Handler(void* btn, uint8_t event) { if( event & PRESS_DOWN ){ //do something... }else if( event & PRESS_UP ){ //do something... } } ... ```