杰杰本身写的一个按键驱动,支持单双击、连按、长按;采用回调处理按键事件(自定义消抖时间),使用只需3步,建立按键,按键事件与回调处理函数连接映射,周期检查按键。git
源码地址:github.com/jiejieTop/B…。做者:杰杰github
前几天写了个按键驱动,参考了MulitButton的数据结构的用法,逻辑实现并不同。在这里感谢全部的开源开发者,让我从中学到了不少,同时网络也是一个好平台,也但愿全部的开发者能造成良性循环,从网络中学知识,回馈到网络中去。感谢MulitButton的做者0x1abin,感谢两位rtt的大佬:大法师、流光。网络
Buttondrive是一个小巧的按键驱动,支持单击、双击、长按、连续触发等(后续能够在按键控制块中添加触发事件),理论上可无限量扩展Button,Buttondrive采用按键触发事件回调方式处理业务逻辑,支持在RTOS中使用,我目前仅在RT-Thread上测试过。写按键驱动的目的是想要将用户按键逻辑与按键处理事件分离,用户无需处理复杂麻烦的逻辑事件。数据结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nhPnwqF-1571148176402)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/1.png?raw=true)]函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtGvjTjq-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/2.png?raw=true)]工具
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QUypOh2s-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/3.png?raw=true)]开发工具
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LfsbuM1W-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/4.png?raw=true)]测试
Button_t Button1;
Button_t Button2; 复制代码
Button_Create("Button1", //按键名字
&Button1, //按键句柄
Read_Button1_Level, //按键电平检测函数接口
BTN_TRIGGER); //触发电平
......复制代码
Button_Attach(&Button1,BUTTON_DOWM,Btn2_Dowm_CallBack); //按键单击
Button_Attach(&Button1,BUTTON_DOUBLE,Btn2_Double_CallBack); //双击
Button_Attach(&Button1,BUTTON_LONG,Btn2_Long_CallBack); //长按
.......复制代码
Button_Process(); //须要周期调用按键处理函数复制代码
须要用户实现的 2 个函数:ui
uint8_t Read_Button1_Level(void)
{
return GPIO_ReadInputDataBit(BTN1_GPIO_PORT,BTN1_GPIO_PIN);
}
uint8_t Read_Button2_Level(void)
{
return GPIO_ReadInputDataBit(BTN2_GPIO_PORT,BTN2_GPIO_PIN);
}
// 这是我在stm32上简单测试的伪代码,以实际源码为准
复制代码
void Btn1_Dowm_CallBack(void *btn)
{
PRINT_INFO("Button1 单击!");
}
void Btn1_Double_CallBack(void *btn)
{
PRINT_INFO("Button1 双击!");
}
void Btn1_Long_CallBack(void *btn)
{
PRINT_INFO("Button1 长按!");
Button_Delete(&Button2);
PRINT_INFO("删除Button1");
Search_Button();
}复制代码
Button_drive开放源码,按键控制块采用数据结构方式,按键事件采用枚举类型,确保不会重复,也便于添加用户须要逻辑,采用宏定义方式定义消抖时间、连按触发时间、双击时间间隔、长按时间等,便于修改。同时全部被建立的按键采用单链表方式连击,用户只管建立,无需理会按键处理,只需调用Button_Process()
便可,在函数中会自动遍历全部被建立的按键。支持按键删除操做,用户无需在代码中删除对应的按键建立于映射连接代码,也无需删除关于按键的任何回调事件处理函数,只需调用Button_Delete()
函数便可,这样子,就不会处理关于被删除按键的任何状态。固然目前按键内存不会释放,若是使用os的话,建议释放按键内存。spa
/*
每一个按键对应1个全局的结构体变量。
其成员变量是实现消抖和多种按键状态所必须的
*/
typedef struct button
{
/* 下面是一个函数指针,指向判断按键手否按下的函数 */
uint8_t (*Read_Button_Level)(void); /* 读取按键电平函数,须要用户实现 */
char Name[BTN_NAME_MAX];
uint8_t Button_State : 4; /* 按键当前状态(按下仍是弹起) */
uint8_t Button_Last_State : 4; /* 上一次的按键状态,用于判断双击 */
uint8_t Button_Trigger_Level : 2; /* 按键触发电平 */
uint8_t Button_Last_Level : 2; /* 按键当前电平 */
uint8_t Button_Trigger_Event; /* 按键触发事件,单击,双击,长按等 */
Button_CallBack CallBack_Function[number_of_event];
uint8_t Button_Cycle; /* 连续按键周期 */
uint8_t Timer_Count; /* 计时 */
uint8_t Debounce_Time; /* 消抖时间 */
uint8_t Long_Time; /* 按键按下持续时间 */
struct button *Next;
}Button_t;
复制代码
typedef enum {
BUTTON_DOWM = 0,
BUTTON_UP,
BUTTON_DOUBLE,
BUTTON_LONG,
BUTTON_CONTINUOS,
BUTTON_CONTINUOS_FREE,
BUTTON_ALL_RIGGER,
number_of_event, /* 触发回调的事件 */
NONE_TRIGGER
}Button_Event;
复制代码
#define BTN_NAME_MAX 32 //名字最大为32字节
/* 按键消抖时间40ms, 建议调用周期为20ms
只有连续检测到40ms状态不变才认为有效,包括弹起和按下两种事件
*/
#define CONTINUOS_TRIGGER 0 //是否支持连续触发,连发的话就不要检测单双击与长按了
/* 是否支持单击&双击同时存在触发,若是选择开启宏定义的话,单双击都回调,只不过单击会延迟响应,
由于必须判断单击以后是否触发了双击不然,延迟时间是双击间隔时间 BUTTON_DOUBLE_TIME。
而若是不开启这个宏定义,建议工程中只存在单击/双击中的一个,不然,在双击响应的时候会触发一次单击,
由于双击必须是有一次按下而且释放以后才产生的 */
#define SINGLE_AND_DOUBLE_TRIGGER 1
/* 是否支持长按释放才触发,若是打开这个宏定义,那么长按释放以后才触发单次长按,
不然在长按指定时间就一直触发长按,触发周期由 BUTTON_LONG_CYCLE 决定 */
#define LONG_FREE_TRIGGER 0
#define BUTTON_DEBOUNCE_TIME 2 //消抖时间 (n-1)*调用周期
#define BUTTON_CONTINUOS_CYCLE 1 //连按触发周期时间 (n-1)*调用周期
#define BUTTON_LONG_CYCLE 1 //长按触发周期时间 (n-1)*调用周期
#define BUTTON_DOUBLE_TIME 15 //双击间隔时间 (n-1)*调用周期 建议在200-600ms
#define BUTTON_LONG_TIME 50 /* 持续n秒((n-1)*调用周期 ms),认为长按事件 */
#define TRIGGER_CB(event) \
if(btn->CallBack_Function[event]) \
btn->CallBack_Function[event]((Button_t*)btn)复制代码
Button_Create("Button1",
&Button1,
Read_KEY1_Level,
KEY_ON);
Button_Attach(&Button1,BUTTON_DOWM,Btn1_Dowm_CallBack); //单击
Button_Attach(&Button1,BUTTON_DOUBLE,Btn1_Double_CallBack); //双击
Button_Attach(&Button1,BUTTON_CONTINUOS,Btn1_Continuos_CallBack); //连按
Button_Attach(&Button1,BUTTON_CONTINUOS_FREE,Btn1_ContinuosFree_CallBack); //连按释放
Button_Attach(&Button1,BUTTON_LONG,Btn1_Long_CallBack); //长按
Button_Create("Button2",
&Button2,
Read_KEY2_Level,
KEY_ON);
Button_Attach(&Button2,BUTTON_DOWM,Btn2_Dowm_CallBack); //单击
Button_Attach(&Button2,BUTTON_DOUBLE,Btn2_Double_CallBack); //双击
Button_Attach(&Button2,BUTTON_CONTINUOS,Btn2_Continuos_CallBack); //连按
Button_Attach(&Button2,BUTTON_CONTINUOS_FREE,Btn2_ContinuosFree_CallBack); //连按释放
Button_Attach(&Button2,BUTTON_LONG,Btn2_Long_CallBack); //长按
Get_Button_Event(&Button1);
Get_Button_Event(&Button2);复制代码
流光大佬的要求,让我玩一玩RTT的rtkpgs,打算用Button_drive练一练手吧。
目前我已将按键驱动作成软件包(packages),若是使用RT-Thread操做系统的话,能够在env中直接配置使用!
步骤以下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gG59d3Yn-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/5.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-amGYFH8P-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/6.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O0a0wqdi-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/7.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5sGP0CE-1571148176405)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/8.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EYxByBVm-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/9.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0pdTFhz-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/10.png?raw=true)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXNX8VeJ-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/11.png?raw=true)]
buildpkg 是用于生成 RT-Thread package 的快速构建工具。
一个优秀的 package 应该是这样的:
为了方便快速的生成 RT-Thread package 规范化模板 以及 减轻开源仓库迁移 RT-Thread 的前期准备工做的负担,基于此目的的 buildpkg 应运而生,为开发 Rt-Thread 的 package 的开发者提供辅助开发工具。
buildpkg.exe make pkgdemo
buildpkg.exe make cstring https://github.com/liu2guang/cstring.git
buildpkg.exe update pkgname
长参数 |
短参数 | 描述 |
---|---|---|
--version=v1.0.0 | -v v1.0.0 | 设置 package 的版本 |
--license=MIT | -l MIT | 设置 package 所遵循的版权协议 |
--submodule | -s | 删除 git 子模块 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CT6Hxh28-1571148176408)(/figures/buildpkg.gif)]
相关代码能够在公众号后台获取。欢迎关注“物联网IoT开发”公众号