GitHub开源按键状态机lwbtn

原项目地址:https://github.com/MaJerle/lwbtn

移植教程

第一步:找到lwbtn文件



点进这个文件夹,顺着点进去,就可以看到一共那么几个文件:



这几个就是接下来要移植的按键系统。

第二步:文件放入自己的工程

这里要注意的一个点:将 lwbtn_opts_template.h 文件改名为:lwbtn_opts.h 作为用户头文件,并且在keil中新建lwbtn_opts_use.c 文件作为用户.c文件,接下来我们就是要在这个俩个文件中编写我们所需要的函数。

结束以上操作后在keil中有那么几个文件:

第三步:了解各个文件的作用

lwbtn.c

大佬编写的按键状态机的各种状态库以及逻辑判断,这里用户不需要管,也不需要修改。

lwbtn.h

就是 lwbtn.c 状态库的头文件,用户也不需要管,不需要修改。

lwbtn_opt.h

包含按键各种事件的设置,有按下消抖、释放消抖、长按时间等等设置,用户可以在此修改宏定义来设置按键功能。

lwbtn_opts_use.c

用户编写函数的文件,在此增加按键处理函数等

lwbtn_opts.h

就是 lwbtn_opts_use.c 文件的头文件

第五步:在 lwbtn_opts_use.c 文件增加所需函数

点击查看代码
#include "lwbtn_opts.h"

/**
* @brief 全局变量,记录当前触发的按键编号
*
* - 0: 无按键
* - 1: KEY0
* - 2: KEY1
* - 3: KEY2
* - 4: KEY_UP
* 必须要 lwbtn_keys = btn_index + 1; 以摆脱为0时的按键状态
*/
uint8_t lwbtn_keys; /* 为每个按键定义GPIO参数 */
lwbtn_argdata_port_pin_state_t key0_gpio = {
.port = KEY0_GPIO_Port, /* KEY0的GPIO端口 */
.pin = KEY0_Pin, /* KEY0的GPIO引脚 */
.state = 0 /* 低电平触发 */
}; lwbtn_argdata_port_pin_state_t key1_gpio = {
.port = KEY1_GPIO_Port, /* KEY1的GPIO端口 */
.pin = KEY1_Pin, /* KEY1的GPIO引脚 */
.state = 0 /* 低电平触发 */
}; lwbtn_argdata_port_pin_state_t key2_gpio = {
.port = KEY2_GPIO_Port, /* KEY2的GPIO端口 */
.pin = KEY2_Pin, /* KEY2的GPIO引脚 */
.state = 0 /* 低电平触发 */
}; lwbtn_argdata_port_pin_state_t key_up_gpio = {
.port = KEY_UP_GPIO_Port, /* KEY_UP的GPIO端口 */
.pin = KEY_UP_Pin, /* KEY_UP的GPIO引脚 */
.state = 1 /* 高电平触发 */
}; /* 定义按钮数组,每个按钮绑定对应的GPIO参数 */
lwbtn_btn_t buttons[] = {
{ .arg = &key0_gpio }, /* KEY0 */
{ .arg = &key1_gpio }, /* KEY1 */
{ .arg = &key2_gpio }, /* KEY2 */
{ .arg = &key_up_gpio }, /* KEY_UP */
}; /**
* @brief 获取按钮的当前状态
*
* 通过读取GPIO引脚的电平,判断按钮是否处于激活状态。
*
* @param lwobj: LwBTN实例(未使用)
* @param btn: 按钮实例,包含GPIO参数
* @return uint8_t: 1表示按钮激活,0表示按钮未激活
*/
uint8_t get_button_state(lwbtn_t* lwobj, lwbtn_btn_t* btn)
{
lwbtn_argdata_port_pin_state_t* cfg = btn->arg;
uint8_t pin_state = HAL_GPIO_ReadPin(cfg->port, cfg->pin);
return (pin_state == cfg->state) ? 1 : 0; // 返回激活状态
} /**
* @brief 按钮事件处理函数
*
* 根据LwBTN库触发的事件类型,处理按钮的按下、释放、单击、双击和长按事件。
* * 每一个事件都会触发一个回调 *
*
* @param lwobj: LwBTN实例
* @param btn: 触发事件的按钮实例
* @param evt: 事件类型(按下、释放、单击、长按等)
*/
void button_event_handler(lwbtn_t* lwobj, lwbtn_btn_t* btn, lwbtn_evt_t evt)
{
// 根据按钮索引识别具体按键
uint8_t btn_index = (btn - lwobj->btns);
switch (evt) {
/* 按键按下事件 */
case LWBTN_EVT_ONPRESS:
// lwbtn_keys = btn_index + 1; // 记录按键编号
break;
/* 按键释放事件 */
case LWBTN_EVT_ONRELEASE:
// lwbtn_keys = btn_index + 1; // 记录按键编号
break;
/* 单击/双击事件 */
case LWBTN_EVT_ONCLICK:
if (btn->click.cnt == 2) { /* 双击 */
lwbtn_keys = btn_index + 1; // 记录按键编号
btn->click.cnt = 0; // 重置计数器
printf("按键%d 双击\r\n",lwbtn_keys);
} else { /* 单击 */
lwbtn_keys = btn_index + 1; // 记录按键编号
printf("按键%d 单击\r\n",lwbtn_keys);
}
break;
/* 长按事件 */
case LWBTN_EVT_KEEPALIVE:
lwbtn_keys = btn_index + 1; // 记录按键编号
printf("按键%d 长按保持\n", lwbtn_keys);
break;
}
} /**
* @brief 初始化按钮管理器
*
* 使用LwBTN库初始化按钮管理器,绑定按钮数组、状态读取函数和事件处理函数。
*/
void button_init(void)
{
lwbtn_init_ex(NULL, buttons, BUTTON_COUNT, get_button_state, button_event_handler);
} /**
* @brief 处理按键状态
*
* 定期调用此函数以处理按键状态,触发事件回调。
*/
void get_btn()
{
uint32_t tick = 0;
tick = HAL_GetTick(); // 获取当前系统时间
lwbtn_process(tick); // 处理按键状态
}

第六步:在lwbtn_opts.h 文件增加说明

点击查看代码
#ifndef LWBTN_OPTS_H
#define LWBTN_OPTS_H /* 将此文件重命名为 "lwbtn_opts.h" 以适应您的应用程序 */ /*
* 打开 "include/lwbtn/lwbtn_opt.h" 并
* 复制并在此处替换您希望更改的设置值
*/ #include "main.h" // 此处修改为用户的主头文件 #define BUTTON_COUNT (sizeof(buttons) / sizeof(buttons[0])) extern void button_init(void);
void get_btn(); extern uint8_t lwbtn_keys; #endif /* LWBTN_OPTS_H */

第七步:主函数使用

点击查看代码
void main(void) {

	button_init();

	while(1) {
get_btn(); // 持续获取按键值
printf("%d\r\n", lwbtn_keys); // 打印出按下的按键
if(lwbtn_keys == ??) {
...
}
}
}

使用说明

在 button_event_handler 按钮事件处理函数中,按键按下分为:按下,释放;按下类型又分为:单击、双击、持续按下。

这每一个状态/事件,进行过后,其都会进行一次回调,即回到主函数一次,故也是分为了1、按下 2、释放 3、单击 4、双击 5、持续按下 五个回调状态。

你可以在 button_event_handler 函数中,switch 中,每 case 一个状态,就可以在此状态下执行某些操作

在本移植文件中,仅在按键单击和双击以及持续按下这三个状态中进行了 lwbtn_keys 变量赋值,并且打印当前状态。

目前测试得,同时按下四个按键,无论是单击、双击,还是持续按下,都有及其灵敏的反应,十分推荐使用!

源代码提供

包括原项目代码和我修改移植好的代码,下载链接:

超好用的开源按键状态系统lwbtn

【STM32系列】超好用的开源按键状态系统lwbtn,以及超详细的移植教程的更多相关文章

  1. stm32开发笔记(三):stm32系列的GPIO基本功能之输出驱动LED灯、输入按键KEY以及Demo

    前言   stm32系列是最常用的单片机之一,不同的版本对应除了引脚.外设.频率.容量等'不同之外,其开发的方法是一样的.  本章讲解使用GPIO引脚功能驱动LED灯和接收Key按钮输入.   STM ...

  2. STM32系列ARM单片机介绍

    STM32系列基于专为要求高性能.低成本.低功耗的嵌入式应用专门设计的ARM Cortex-M3内核.按性能分成两个不同的系列:STM32F103"增强型"系列和STM32F101 ...

  3. Keil MDK STM32系列(三) 基于标准外设库SPL的STM32F407开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  4. STM32系列命名规则

    转自:STM32系列命名规则 STM32 F 103 C 6 T 7 xxx 1 2 3 4 5 6 7 8 第1部分:产品系列名,固定为STM32 第2部分:产品类型:F表示这是Flash产品,目前 ...

  5. GGTalk——C#开源即时通讯系统源码介绍系列(一)

    坦白讲,我们公司其实没啥技术实力,之所以还能不断接到各种项目,全凭我们老板神通广大!要知道他每次的饭局上可都是些什么人物! 但是项目接下一大把,就凭咱哥儿几个的水平,想要独立自主.保质保量保期地一个个 ...

  6. STM32系列第15篇--灵活的静态存储控制器FSMC

    源: STM32系列第15篇--灵活的静态存储控制器FSMC

  7. 超全的 Vue 开源项目合集,签收一下

    超全的 Vue 开源项目合集,签收一下 xiaoge2016 前端开发 1周前 作者:xiaoge2016 链接: https://my.oschina.net/u/3018050/blog/2049 ...

  8. stm32开发笔记(二):stm32系列使用V3.5固件库的帮助文件以及GPIO基本功能(一)

    前言   stm32系列是最常用的单片机之一,不同的版本对应除了引脚.外设.频率.容量等'不同之外,其开发的方法是一样的.  本章讲解使用库函数使用GPIO引脚功能.   补充   本文章为多年前学习 ...

  9. .NET平台系列12 .NET未来之开源.NET Core

    系列目录     [已更新最新开发文章,点击查看详细] 微软于2014年11月推出了.NET Core 1.0..NET Core的目标是从我们在过去12年中对.NET Framework的构建.交付 ...

  10. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

随机推荐

  1. python 简单socket

    简介 python 简单socket code import socket HOST = '103.46.128.53' PORT = 24876 BUFSIZ = 1024 ADDR = (HOST ...

  2. U盘安装可能会遇见UEFI的问题,使用easyBCD安装即可。

    参考链接 CSDN博客 Tips 关于 (hd0,0) 如果出现 File not find的问题那么使用,(hd0,1) 后面的数字变一下,主要根据是,windows 的磁盘管理中的C盘的系统盘的序 ...

  3. opengl 坐标系

    简介 世界坐标是OpenGL中用来描述场景的坐标,Z+轴垂直屏幕向外,X+从左到右,Y+轴从下到上,是右手笛卡尔坐标系统.

  4. 最新版本 IDEA 2022.2.X 2022.3.X 激活(附激活码)适用于DataGrip

    背景 截止至2023-02-14,IDEA最新版本为2022.3.2,对于某些想体验最新版IDEA却暂时没法入正的开发者来说,不能体验新版非常遗憾. 重置IDEA体验版的插件IDE Eval Rese ...

  5. RestCloud API管理门户,API接口治理平台

    API管理门户主要管理企业内部及外部的所有API,RestCloud API门户支持通过Java代码中的注解自动扫描生成API文档.通过OpenAPI3.0标准文档导入.JSON格式数据导入等多种方式 ...

  6. SciTech-EECS-Sensor:TI的 4-20mA 环路供电系统实现高达 100m 的液位测量,具有高测距精度和低功耗

    https://www.ti.com.cn/zh-cn/featured-applications-content/sensors/mmwave-radar/industrial-mmwave-lev ...

  7. Win11正式版电脑回收站为什么显示灰色的问题

    一些雨林木风官网的win11正式版用户发现桌面上的回收站图标显示是灰色,点击无法进行,不能操作.这该如何解决呢?我们可以先尝试删除回收站图标,并在图标设置中添加相同的图标.此外,雨林木风小编再来分享其 ...

  8. win11专业版取消开机密码的问题

    许多雨林木风官网的小伙伴在第一次安装win11专业版的时候,设置了帐号和密码,但是每次电脑开机都要输入密码,使用起来非常不方便.那么,我们要如何取消开机密码呢?接下来,ylmf系统小编就来分享详细的操 ...

  9. Windows11以后可能再无控制面板了

    msdn123发现对于微软官方而言,Windows11系统上控制面板的影响真的是越来越小,简直就是被抛弃的节奏,而且说不定在不久的将来,win11正式版发布可能再无控制面板了. 在Windows11系 ...

  10. bootstrapTable的使用及表格的导出

    https://www.pudn.com/news/6278bf1977d3727348162d84.html 代码:bootstrap: bootstrap的使用示例.包括bootstrapTabl ...