70 lines
2.0 KiB
C
70 lines
2.0 KiB
C
#pragma once
|
||
|
||
#include <stdio.h>
|
||
#include <stdint.h>
|
||
#include <stdbool.h>
|
||
#include <unistd.h> // 如果在裸机下,用平台自带的延时函数替代
|
||
#include "../pin_io/pin_io.h"
|
||
#include "../../config/board_config.h"
|
||
#include "../../config/app_config.h"
|
||
#include "sys_log.h"
|
||
#include "os/os.h"
|
||
#include "device.h"
|
||
#include "../led_strip/led_strip.h"
|
||
#include "protocol/stmisp.h"
|
||
|
||
// 按键事件类型
|
||
typedef enum {
|
||
EVT_NONE = 0, // 无事件
|
||
EVT_PRESS_DOWN, // 按下
|
||
EVT_PRESS_UP, // 松开
|
||
EVT_SINGLE_CLICK, // 单击
|
||
EVT_DOUBLE_CLICK, // 双击
|
||
EVT_LONG_PRESS, // 长按释放
|
||
EVT_SINGLE_LONG_PRESS // 单击后长按
|
||
} button_event_t;
|
||
|
||
// 回调函数原型
|
||
typedef void (*button_cb_t)(button_event_t evt);
|
||
|
||
// 配置参数
|
||
#define DEBOUNCE_TICKS 3 // 连续3次读到新值才确认变化
|
||
#define LONG_PRESS_TICKS 100 // 100*SCAN_INTERVAL_US >=1s 触发长按阈值
|
||
#define DOUBLE_CLICK_WINDOW 30 // 30*SCAN_INTERVAL_US <=300ms 双击间隔窗口
|
||
#define SCAN_INTERVAL_US 10000 // 10ms 扫描一次
|
||
|
||
// 按键处理结构体
|
||
typedef struct {
|
||
bool (*read_pin)(void); // 读取 GPIO,按下返回 true
|
||
button_cb_t callback; // 事件回调
|
||
|
||
uint8_t stable_state; // 去抖后稳定状态
|
||
uint8_t debounce_cnt; // 去抖计数
|
||
uint16_t tick_cnt; // 持续按下或间隔计数
|
||
uint8_t state; // 状态机状态
|
||
uint8_t click_count; // 短按计数
|
||
} button_t;
|
||
|
||
extern bool key_single_click,key_press_down,key_press_up;
|
||
void _work_button(void *arg);
|
||
/**
|
||
* @brief 初始化按键
|
||
*/
|
||
void button_work_init();
|
||
/**
|
||
* @brief 设置boot按键输出
|
||
*/
|
||
void boot_set(uint8_t value);
|
||
/**
|
||
* @brief 设置boot按键为高阻态
|
||
*/
|
||
void boot_set_high_z(void);
|
||
|
||
void key_test(void);
|
||
|
||
void boot_set_2(uint8_t value);
|
||
|
||
void boot_set_high_z_2(void);
|
||
|
||
bool key_get_status(void);
|