Files

96 lines
3.3 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.
/*
* Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
* All rights reserved.
*/
#ifndef MULTI_BUTTON_H
#define MULTI_BUTTON_H
#include <stdint.h>
#include <string.h>
/* 版本信息 */
#define MULTIBUTTON_VERSION_MAJOR 1
#define MULTIBUTTON_VERSION_MINOR 1
#define MULTIBUTTON_VERSION_PATCH 1
/* 配置常量 - 可根据需求修改 */
#define TICKS_INTERVAL 5 /* 定时器轮询间隔,单位:毫秒 */
#define DEBOUNCE_TICKS 3 /* 消抖滤波深度最大7 (0~7) */
#define SHORT_TICKS (300 / TICKS_INTERVAL) /* 短按阈值 */
#define LONG_TICKS (1000 / TICKS_INTERVAL) /* 长按阈值 */
#define PRESS_REPEAT_MAX_NUM 15 /* 最大重复计数器值 */
/* 编译时检查debounce_cnt 是3位域最大值为7 */
#if DEBOUNCE_TICKS > 7
#error "DEBOUNCE_TICKS exceeds 3-bit field maximum (7)"
#endif
/* 前向声明 */
typedef struct _Button Button;
/* 按键回调函数类型 */
typedef void (*BtnCallback)(Button* handle, void* user_data);
/* 按键事件类型 */
typedef enum {
BTN_PRESS_DOWN = 0, /* 按键按下 */
BTN_PRESS_UP, /* 按键释放 */
BTN_PRESS_REPEAT, /* 重复按下检测 */
BTN_SINGLE_CLICK, /* 单击完成 */
BTN_DOUBLE_CLICK, /* 双击完成 */
BTN_LONG_PRESS_START, /* 长按开始 */
BTN_LONG_PRESS_HOLD, /* 长按保持 */
BTN_EVENT_COUNT, /* 事件总数 */
BTN_NONE_PRESS /* 无事件 */
} ButtonEvent;
/* 按键状态机状态 */
typedef enum {
BTN_STATE_IDLE = 0, /* 空闲状态 */
BTN_STATE_PRESS, /* 按下状态 */
BTN_STATE_RELEASE, /* 释放后等待超时 */
BTN_STATE_REPEAT, /* 重复按下状态 */
BTN_STATE_LONG_HOLD /* 长按保持状态 */
} ButtonState;
/* 按键结构体 */
struct _Button {
uint16_t ticks; /* tick计数器 */
uint8_t repeat : 4; /* 重复计数器 (0-15) */
uint8_t event : 4; /* 当前事件 (0-15) */
uint8_t state : 3; /* 状态机状态 (0-7) */
uint8_t debounce_cnt : 3; /* 消抖计数器 (0-7) */
uint8_t active_level : 1; /* 有效GPIO电平 (0或1) */
uint8_t button_level : 1; /* 当前按键电平 */
uint8_t button_id; /* 按键标识符 */
uint8_t (*hal_button_level)(uint8_t button_id); /* HAL读取GPIO函数 */
BtnCallback cb[BTN_EVENT_COUNT]; /* 回调函数数组 */
void* user_data; /* 传递给回调的用户上下文指针 */
Button* next; /* 链表中的下一个按键 */
};
#ifdef __cplusplus
extern "C" {
#endif
/* 公共API函数 */
void button_init(Button* handle, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t button_id);
void button_attach(Button* handle, ButtonEvent event, BtnCallback cb, void* user_data);
void button_detach(Button* handle, ButtonEvent event);
ButtonEvent button_get_event(Button* handle);
int button_start(Button* handle);
void button_stop(Button* handle);
void button_ticks(void);
/* 工具函数 */
uint8_t button_get_repeat_count(Button* handle);
void button_reset(Button* handle);
int button_is_pressed(Button* handle);
#ifdef __cplusplus
}
#endif
#endif /* MULTI_BUTTON_H */