🇺🇸 English | 🇨🇳 简体中文
📌 项目简介
这是一个基于强大的 easy_button 库的入门级应用层封装,专注于常见按键使用场景,让开发者能够快速上手 easy_button 的核心功能。通过硬件抽象层(HAL)、应用层和适配层的分离设计,实现了高度的跨平台可移植性。
💡 关于 easy_button 核心库:easy_button 是一个功能丰富的嵌入式按键处理库,支持单击、多击、长按、组合键、防抖处理等高级功能。本封装库仅使用了其中的常用功能,如需更多高级特性,请参考 easy_button 官方文档。
- C99 兼容的编译器
- 支持 GPIO 和系统时钟的嵌入式平台
- easy_button 核心库
本项目已将 easy_button 核心库作为 Git 子模块集成,获取完整项目(包含依赖库):
# 克隆项目并自动获取子模块
git clone --recursive https://github.com/Sighthesia/easy_button-Application.git
# 或者分步操作
git clone https://github.com/Sighthesia/easy_button-Application.git
cd easy_button-Application
git submodule update --init --recursive子模块包含的核心文件:
easy_button/ebtn/ebtn.h- 核心头文件easy_button/ebtn/ebtn.c- 核心实现easy_button/ebtn/bit_array.h- 位数组操作
更新子模块到最新版本:
git submodule update --remote easy_button- STM32G030
- STM32H750
- CH32V203
easy_button-Application/
├── ebtn_APP.c/h # 应用层接口和初始化
├── ebtn_APP_HAL.c/h # 硬件抽象层(HAL)
├── ebtn_APP_Keys.c/h # 按键引脚配置和参数
├── ebtn_APP_Event.c/h # 按键事件回调处理
└── easy_button/ # easy_button 核心库子模块
├── ebtn/
│ ├── ebtn.h # 核心头文件
│ ├── ebtn.c # 核心实现
│ └── bit_array.h # 位数组操作
├── example_test.c # 测试示例
├── example_user.c # 用户交互示例
└── README.md # 核心库说明文档
目标:实现平台相关的底层函数
-
修改头文件包含
打开
ebtn_APP_HAL.h,包含适合你平台的 GPIO 和系统时钟头文件:// 示例:STM32F1 系列 #include "stm32f1xx_hal.h" // 示例:CH32V 系列 #include "ch32v20x.h"
- 默认包含
"mian.h",通常包含了GPIO_TypeDef等平台相关定义,如仍报错可包含具体文件。
- 默认包含
-
实现核心回调函数
在
ebtn_APP_HAL.c中实现两个关键回调函数:// 读取指定引脚的逻辑电平 uint8_t ebtn_HAL_Read_Pin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) { return (uint8_t)HAL_GPIO_ReadPin(GPIOx, GPIO_Pin); // STM32 HAL } // 获取当前系统滴答计数(毫秒) uint32_t ebtn_HAL_Get_Tick(void) { return HAL_GetTick(); // STM32 HAL }
目标:定义硬件引脚映射和按键行为
-
定义按键 ID
在
ebtn_APP_Keys.h中定义按键 ID:typedef enum { KEY_1 = 0, KEY_2, KEY_3, KEY_4, // 添加更多按键... KEYS_COUNT // 按键总数 } key_enum_t;
-
配置按键硬件映射
在
ebtn_APP_Keys.c中填写keys_config_list[]数组:key_config_t keys_config_list[] = { {KEY_1, GPIOA, GPIO_PIN_0, EBTN_ACTIVE_LOW}, // PA0,低电平有效 {KEY_2, GPIOA, GPIO_PIN_1, EBTN_ACTIVE_HIGH}, // PA1,高电平有效 {KEY_3, GPIOB, GPIO_PIN_2, EBTN_ACTIVE_LOW}, // PB2,低电平有效 // 添加更多按键配置... };
-
调整时间参数(可选)
根据需要修改以下宏定义:
#define DEBOUNCE_TIME 20 // 防抖时间(毫秒) #define CLICK_AND_PRESS_MAX_TIME 200 // 长按判定阈值(毫秒) #define KEEPALIVE_TIME_PERIOD 500 // 长按周期(毫秒) #define MAX_CLICK_COUNT 3 // 最大连击次数
-
配置组合键(可选)
如果需要组合键,添加到
combo_keys_config_list[]数组:const combo_config_t combo_keys_config_list[] = { COMBO_KEYS(COMBO_KEY_1, KEY_1, KEY_2), // 按键1+按键2 COMBO_KEYS(COMBO_KEY_2, KEY_1, KEY_3, KEY_4), // 按键1+按键3+按键4 };
目标:定义按键事件的自定义处理逻辑
在 ebtn_APP_Event.c 中找到 ebtn_APP_Event() 函数,根据按键 ID 和事件类型实现相应的处理逻辑:
void ebtn_APP_Event(struct ebtn_btn *btn, ebtn_evt_t evt)
{
switch (btn->key_id)
{
case KEY_1:
if (evt == EBTN_EVT_ONPRESS)
{
// 按键1按下处理
}
else if (evt == EBTN_EVT_ONRELEASE)
{
// 按键1释放处理
}
else if (evt == EBTN_EVT_ONCLICK)
{
if (btn->click_cnt == 1)
{
// 单击处理
}
else if (btn->click_cnt == 2)
{
// 双击处理
}
}
else if (evt == EBTN_EVT_KEEPALIVE)
{
if (btn->keepalive_cnt == 1)
{
// 长按1次周期处理
}
}
break;
case KEY_2:
// 按键2的处理逻辑...
break;
case COMBO_KEY_1:
// 组合键1的处理逻辑...
break;
default:
break;
}
}事件类型说明:
EBTN_EVT_ONPRESS- 按键按下事件EBTN_EVT_ONRELEASE- 按键释放事件EBTN_EVT_ONCLICK- 单击/多击事件(通过ebtn->click_cnt区分)EBTN_EVT_KEEPALIVE- 长按保持事件(通过ebtn->keepalive_cnt计数)
目标:初始化按键模块并定期处理按键状态
-
在系统初始化中调用:
#include "ebtn_APP.h" // 包含头文件 int main(void) { // 系统初始化... ebtn_APP_Keys_Init(); // 初始化按键模块 while (1) { ebtn_APP_Process(); // 定期处理按键事件(建议5-20ms) // 其他应用逻辑... HAL_Delay(10); } }
-
或在定时器中断中调用:
void TIM_IRQHandler(void) { if (/* 定时器中断条件 */) { ebtn_APP_Process(); // 每10-20ms调用一次 } }
void ebtn_APP_Keys_Init(void); // 初始化按键模块
void ebtn_APP_Process(void); // 处理按键事件(需定期调用)如需更多查询功能,可以直接使用 easy_button 核心库提供的API:
// 通过按键ID获取按键实例
ebtn_btn_t *btn = ebtn_get_btn_by_key_id(KEY_1);
// 检查按键是否处于激活状态
int is_active = ebtn_is_btn_active(btn);
// 检查按键是否正在处理中
int in_process = ebtn_is_btn_in_process(btn);
// 检查是否有任何按键正在处理(用于低功耗)
int any_in_process = ebtn_is_in_process();注意:使用核心库API前,请包含头文件 #include "ebtn.h"
A: 在 ebtn_APP_Keys.h 中添加新的 KEY_X 枚举值,然后在 ebtn_APP_Keys.c 中更新 keys_config_list[] 数组配置。
A: 只需修改 ebtn_APP_HAL.c/h 中的底层函数实现(如 GPIO_ReadPin、SysTick),其他文件无需修改。
A: 在 ebtn_APP_Event.c 中实现自己的处理函数,并在 ebtn_APP_Event() 中根据按键 ID 和事件类型调用。
A: 请确保已正确获取子模块。运行 git submodule update --init --recursive 来获取 easy_button 核心库文件。
A: 修改 ebtn_APP_Keys.h 中的 DEBOUNCE_TIME 宏定义,单位为毫秒。
A: 运行 git submodule update --remote easy_button 来更新子模块到最新版本。
- ✅ 单击/多击检测 - 支持最多连续点击检测
- ✅ 长按检测 - 支持多级长按(通过
keepalive_cnt实现) - ✅ 组合键支持 - 支持多按键组合
- ✅ 防抖处理 - 硬件级防抖,可配置防抖时间
- ✅ 低功耗支持 - 提供睡眠状态检测接口
- ✅ 跨平台移植 - 硬件抽象层设计,易于移植
如果某些按键需要特殊的时间参数,可以在 ebtn_APP_Keys.c 中使用特殊配置:
// 定义特殊参数
static ebtn_btn_param_t long_press_params = EBTN_PARAMS_INIT(
20, // 防抖时间
0, // 释放防抖时间
20, // 最短按下时间
100, // 最长短按时间
200, // 多击间隔
1000, // 长按周期(1秒)
5 // 最大连击次数
);
// 应用特殊参数
const special_key_list_t special_keys_list[] = {
KEY_SPECIAL_CONFIG(KEY_1, long_press_params),
};使用 ebtn_is_in_process() 检查是否可以进入深度睡眠:
if (!ebtn_is_in_process())
{
// 安全进入深度睡眠模式
HAL_PWR_EnterSTOPMode();
}如有任何问题或建议,欢迎提交 Issue 或 Pull Request!
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
第三方许可证:本项目使用的 easy_button 核心库 采用 Apache-2.0 许可证。
🤖 ☝️🤓 由 GitHub Copilot 辅助开发