# STM32_Button_Cplus **Repository Path**: Sevenfite/stm32-button-cplus ## Basic Information - **Project Name**: STM32_Button_Cplus - **Description**: 用C++面向对象的思想,实现stm32按键功能,实现了每个按键独立的短按,长按 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-02-17 - **Last Updated**: 2024-07-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # STM32_Button_Cplus #### 介绍 用C++面向对象的思想,实现stm32按键功能,实现了每个按键独立的短按,长按 把按键抽象出来,实现与顶层解耦,在这里实现了非延时的软件消抖,多按键同时检测不冲突 #### 软件架构 软件架构说明 #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用方法 这里不讲C++的使用 1.先创建一个Button对象 ```c++ //Button(const int buttonId, bool (*const read_Pin)(), const bool active_level) //输入按键ID,读电平的方法,有效电平 Button button1(1, []()->bool{return (bool)HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_5);}, 0); ``` 2.修改常量 ```c++ /**********在这里定义一些常量**********/ const int TICKS_INTERVAL = 1; // 轮询间隔,单位ms const int DEBOUNCE_TICKS = 5; // 消抖时间,单位*TICKS_INTERVAL const int SHORT_INTERVAL = 250; // 短按时间,单位ms,双击时间间隔小于这个的一半 const int LONG_INTERVAL = 1000; // 长按时间,单位ms ``` 常量的意义 DEBOUNCE_TICKS 消抖的时间间隔,比如代码的意义为连续5次均检测到同一电平,即认为电平正确 SHORT_INTERVAL 短按时间,按下的时间大于短按时间,小于长按触发时间即认为是只按一次, 按下时间如果短于短按时间,但是松手后在1/2短按时间内没有按下第二次,则认为是只按一次,如果按下第二次,则认为是双击。 如果已经触发长按,则每个短按时间一到,就再次触发PRESS_LONG_HOLD事件 LONG_INTERVAL 首次长按的触发时间 如果不使用定时器,而是使用轮询的方式,TICKS_INTERVAL不可确定,则修改`button.c`中的 `uint16_t Button::getInterval(){return TICKS_INTERVAL;}` 这个函数是用来每次返回与上次调用的时间间隔的,可以改成自己的实现方式,以适配轮询 3.在定时器中定时执行函数 ```c++ button1.tick_handler(); ``` 4.回调函数 可以使用 `bool Button::register_callback(const callback_t callback, const PressEvent event);` 来注册回调函数 ,回调函数在事件被触发后会调用 传入的`PressEvent`为 PRESS_SINGLE, // 单击 PRESS_DOUBLE, // 双击 PRESS_LONG_START, // 长按开始,只触发一次 PRESS_LONG_HOLD, // 长按保持,每隔一段时间触发一次 中的一个,以上4个事件均会触发对应的回调函数,回调函数可以动态更改 当然,回调函数的触发方式会产生一定的局限性,也可以不使用回调函数的方式触发,每次回调函数被调用,就会更改按键的事件。那就要自行扫描对象的事件`Button:: PressEvent event; // 按键事件`来实现,**还未实现此功能** #### 功能说明 在轮询函数 `tick_handler()`中,把连续几次扫描到同一电平认为是有效,以此来消抖,然后使用一个简单的状态机,来实现状态的切换 |状态|说明 |-----|-----| | None_Press = 0, | 无按键,按下则变为First_Press | First_Press, | 第一次按下,长时间按下变成Long_Press,短时间按下松开后变为连击检测或者单击状态(大于SHORT_INTERVAL为单击) | Press_Check, | 连击检测,在SHORT_INTERVAL的一半时间内按下变为Double_Check,没有按则为单击 | Single_Check, | 单击,在下一次扫描后直接变为无按键 | Double_Check, | 双击,检测松手后变为无按键 | Long_Press, | 长按,不松手一直为长按,松手变为无按键 在状态的切换会伴随事件的产生,然后会有回调函数 **注意:**`PRESS_LONG_START`事件只在刚触发长按时产生,后面的长按事件均为`PRESS_LONG_HOLD`,`PRESS_LONG_HOLD`的触发时间间隔为`SHORT_INTERVAL` #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)