system/btn.h

165 lines
4.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***
* @Author:
* @Date: 2023-07-04 08:26:12
* @LastEditors: xxx
* @LastEditTime: 2023-08-09 22:49:14
* @Description: btn是一个小巧简单易用的事件驱动型按键驱动模块可无限量扩展按键按键事件的回调异步处理方式
* @email:
* @Copyright (c) 2023 by xxx, All Rights Reserved.
*/
/**
使用方法:
1.先申请一个按键结构
struct Button button1;
2.初始化按键对象绑定按键的GPIO电平读取接口read_button_pin() ,后一个参数设置有效触发电平
button_init(&button1, read_button_pin, 0, 0);
3.注册按键事件
button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler);
button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler);
...
4.启动按键
button_start(&button1);
5.设置一个5ms间隔的定时器循环调用后台处理函数
while(1) {
...
if(timer_ticks == 5) {
timer_ticks = 0;
button_ticks();
}
}
*/
#ifndef _BTN_H_
#define _BTN_H_
#ifdef STM32
#include "lib.h"
#else
#include "stdint.h"
#include "string.h"
#endif
// 根据您的需求修改常量。
#define TICKS_INTERVAL 10 // 按钮扫描间隔单位ms
#define DEBOUNCE_TICKS 20 / TICKS_INTERVAL // 按键去抖动时间单位ms
#define SHORT_TICKS (100 / TICKS_INTERVAL) // 短按时间阈值单位ms
#define LONG_TICKS (500 / TICKS_INTERVAL) // 长按时间阈值单位ms
typedef void (*BtnCallback)(void *);
typedef enum
{
ACTIVE_LEVEL_LOW = 0, // 低电平有效
ACTIVE_LEVEL_HIGH, // 高电平有效
} active_level_e;
/***
* @brief
事件 说明
PRESS_DOWN 按键按下,每次按下都触发
PRESS_UP 按键弹起,每次松开都触发
PRESS_REPEAT 重复按下触发变量repeat计数连击次数
SINGLE_CLICK 单击按键事件
DOUBLE_CLICK 双击按键事件
LONG_PRESS_START 达到长按时间阈值时触发一次
LONG_PRESS_HOLD 长按期间一直触发
*/
typedef enum
{
PRESS_DOWN = 0, // 按下
PRESS_UP, // 弹起
PRESS_REPEAT, // 重复按下
SINGLE_CLICK, // 单击
DOUBLE_CLICK, // 双击
LONG_PRESS_START, // 长按开始
LONG_PRESS_HOLD, // 长按保持
number_of_event, // 事件数量
NONE_PRESS // 无按键
} PressEvent;
/***
* @brief 按钮设备结构体
*/
typedef struct Button
{
uint16_t ticks; // 计时器
uint8_t repeat : 4; // 重复计数
uint8_t event : 4; // 事件类型
uint8_t state : 3; // 状态
uint8_t debounce_cnt : 3; // 去抖计数
uint8_t active_level : 1; // 激活电平
uint8_t button_level : 1; // 按钮电平
uint8_t button_id; // 按钮ID
uint8_t button_id_reverse; // 按钮ID反转
uint8_t (*hal_button_Level)(uint8_t button_id_); // 获取按钮引脚电平函数
BtnCallback cb[number_of_event]; // 回调函数数组
struct Button *next; // 下一个按钮句柄
} Button;
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief 初始化按钮设备
* @param handle: 按钮句柄结构体
* @param pin_level: 获取按钮引脚电平函数
* @param active_level: 按钮激活电平
* @param button_id: 按钮ID
* @retval 0: 成功
* @retval -1: 失败
*/
void button_init(struct Button *handle, uint8_t (*pin_level)(uint8_t), active_level_e active_level, uint8_t button_id, uint8_t button_id_reverse);
/**
* @brief 附加按钮事件处理函数
* @param handle: 按钮句柄结构体
* @param event: 按钮事件
* @param cb: 回调函数
* @retval 0: 成功
* @retval -1: 失败
*/
void button_attach(struct Button *handle, PressEvent event, BtnCallback cb);
/**
* @brief 获取按钮事件
* @param handle: 按钮句柄结构体
* @retval 按钮事件
*/
PressEvent get_button_event(struct Button *handle);
/**
* @brief 启动按钮工作
* @param handle: 按钮句柄结构体
* @retval 0: 成功
* @retval -1: 已存在
*/
int button_start(struct Button *handle);
/**
* @brief 停止按钮工作
* @param handle: 按钮句柄结构体
* @retval None
*/
void button_stop(struct Button *handle);
/**
* @brief 后台计时定时器重复调用间隔为5ms
* @param None
* @retval None
*/
void button_ticks(void);
#ifdef __cplusplus
}
#endif
#endif