#ifndef HW_LIB_SIM_KEY_H #define HW_LIB_KEY_H #ifdef __cplusplus extern "C" { #endif #include <stdint.h> #include <string.h> #define KEY_TICKS_INTERVAL 5 // 定时器间隔时间,单位为毫秒 #define DEBOUNCE_TICKS 0 // 按键去抖动计数阈值,最大为7(0 ~ 7) #define SHORT_TICKS (300 / KEY_TICKS_INTERVAL) // 短按阈值,单位为定时器间隔的倍数 #define LONG_TICKS (1000 / KEY_TICKS_INTERVAL) // 长按阈值,单位为定时器间隔的倍数 #define KEY_STOP_FREE 1 // 按键停止释放状态标识 typedef struct Key_List Key_t; // 定义结构体Key_t为Key_List的别名 typedef void (*Key_Callback_t)(Key_t *key); // 定义函数指针类型Key_Callback_t,接受一个Key_t结构体指针参数 typedef enum { KEY_PRESS_DOWN = 0, // 按下事件 KEY_PRESS_UP, // 弹起事件 KEY_PRESS_REPEAT, // 重复按下事件 KEY_SINGLE_CLICK, // 单击事件 KEY_DOUBLE_CLICK, // 双击事件 KEY_LONG_PRESS_START, // 长按开始事件 KEY_LONG_PRESS_HOLD, // 长按保持事件 number_of_event, // 事件总数 KEY_ALL_EVENT, // 所有事件 NONE_PRESS // 无按键事件 } PressEvent; // 定义枚举类型PressEvent,表示按键事件类型 struct Key_List { Key_t *next; // 指向下一个按键结构体的指针 uint16_t ticks; // 计时器 uint8_t repeat: 4; // 按键重复次数,占4位 uint8_t event: 4; // 当前按键事件类型,占4位 uint8_t state: 3; // 按键状态,占3位 uint8_t debounce_cnt: 3; // 按键去抖计数,占3位 uint8_t active_level: 1; // 按键激活电平,占1位 uint8_t key_level: 1; // 当前按键电平,占1位 uint8_t key_id; // 按键ID uint8_t (*hal_key_Level)(uint8_t key_id_); // 函数指针,用于获取按键电平 Key_Callback_t cb[number_of_event]; // 按键事件回调函数数组 }; /** * @brief 初始化按键模块 * @param key: [输入] 指向按键结构体的指针 * @param pin_level: [输入] 获取按键电平的回调函数 * @param active_level: [输入] 激活电平 * @param key_id: [输入] 按键ID * @return void * @example key_init(&my_key, get_pin_level, ACTIVE_HIGH, 1); */ void key_init(Key_t *key, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t key_id); /** * @brief 为按键设置回调函数 * @param key: [输入] 按键结构体指针 * @param event: [输入] 按键事件类型 * @param cb: [输入] 回调函数指针 * @param start: [输入] 是否立即启用 * @return void * @example key_attach(&my_key, PRESS_EVENT_LONG_PRESS, key_callback_func, true); **/ void key_attach(Key_t *key, PressEvent event, Key_Callback_t cb, bool start); /** * @brief 获取按键当前事件 * @param key: [输入] 指向按键结构体的指针 * @return 当前按键事件 * @example PressEvent current_event = get_key_event(&my_key); */ PressEvent get_key_event(Key_t *key); /** * @brief 启动按键检测 * @param key: [输入] 指向按键结构体的指针 * @return 错误码,0表示成功 * @example int result = key_start(&my_key); */ int key_start(Key_t *key); /** * @brief 停止按键检测 * @param key: [输入] 指向按键结构体的指针 * @return void * @example key_stop(&my_key); */ void key_stop(Key_t *key); /** * @brief 按键定时处理函数 * @return void * @example key_ticks(); */ void key_ticks(void); #ifdef __cplusplus } #endif #endif //HW_LIB_SIM_KEY_H