#include "key.h" #include "sertrf.h" button_t btn; cfg_board_pin_io_t key_switch = { .pin = 18, .en_lev = 1,}; cfg_board_pin_io_t boot_switch = { .pin = 18, .en_lev = 0,}; // 新增事件类型 // EVT_DOUBLE_CLICK: 双击 // EVT_SINGLE_LONG_PRESS: 单击后长按 bool key_single_click = 0,key_press_down = 0,key_press_up = 0; static os_work_t work_handler_button; // 用户在此处理按键事件 static void my_button_handler(button_event_t evt) { switch (evt) { case EVT_PRESS_DOWN: //按下 // SYS_LOG_INF("[Event] PRESS_DOWN"); key_press_down = true; key_press_up = false; break; case EVT_PRESS_UP: //松开 // SYS_LOG_INF("[Event] PRESS_UP"); key_press_up = true; key_press_down = false; break; case EVT_SINGLE_CLICK: //单击 key_single_click = true; // SYS_LOG_INF("[Event] SINGLE_CLICK"); break; case EVT_DOUBLE_CLICK: //双击 // SYS_LOG_INF("[Event] DOUBLE_CLICK"); // sertrf_rf_switch(1); // aes_test(); key_test(); break; case EVT_LONG_PRESS: //长按 SYS_LOG_INF("[Event] LONG_PRESS"); Examples_run(); rgb_Indicator_light_off(0); //如果处理有变色,需要该函数先调用 // sertrf_rf_switch(0); break; case EVT_SINGLE_LONG_PRESS: //单击后长按 rgb_Indicator_light_off(0); wifi_mode_switch(NULL); SYS_LOG_INF("[Event] SINGLE_LONG_PRESS"); break; default: break; } } // 初始化按键 static void button_init(button_t *btn, bool (*read_pin)(void), button_cb_t cb) { btn->read_pin = read_pin; btn->callback = cb; btn->stable_state = read_pin() ? 1 : 0; btn->debounce_cnt = 0; btn->tick_cnt = 0; btn->state = 0; btn->click_count = 0; // 新增计数 } // 每次调用间隔 5ms (os_work_later 参数) static void button_scan(button_t *btn) { bool level = btn->read_pin(); // 防抖 if (level != btn->stable_state) { if (++btn->debounce_cnt >= DEBOUNCE_TICKS) { btn->stable_state = level; btn->debounce_cnt = 0; } } else { btn->debounce_cnt = 0; } switch (btn->state) { case 0: // 空闲->按下 if (btn->stable_state) { btn->callback(EVT_PRESS_DOWN); btn->tick_cnt = 0; btn->state = 1; } break; case 1: // 按下计时 btn->tick_cnt++; if (!btn->stable_state) { // 松开 btn->callback(EVT_PRESS_UP); if (btn->tick_cnt < LONG_PRESS_TICKS) { // 短按,统计点击次数 btn->click_count++; btn->tick_cnt = 0; btn->state = 2; // 等待双击 } else { // 长按释放 btn->callback(EVT_LONG_PRESS); btn->click_count = 0; btn->state = 0; } } else if (btn->tick_cnt >= LONG_PRESS_TICKS) { //长按开始 长按后提示 rgb_Indicator_light_on(0, RGB_COLOR_CYAN, 100); // 可加 EVT_LONG_PRESS_START 如需区分开始和持续 } break; case 2: // 等待双击或单击后长按 btn->tick_cnt++; if (btn->stable_state) { // 再次按下 if (btn->click_count == 1) { btn->callback(EVT_PRESS_DOWN); btn->state = 3; // 第二次按下 btn->tick_cnt = 0; } } else if (btn->tick_cnt > DOUBLE_CLICK_WINDOW) { // 超过双击时间窗口 if (btn->click_count == 1) { btn->callback(EVT_SINGLE_CLICK); } btn->click_count = 0; btn->state = 0; } break; case 3: // 第二次按下状态 btn->tick_cnt++; // 单击长按后提示 if(btn->tick_cnt > LONG_PRESS_TICKS) { rgb_Indicator_light_on(0, RGB_COLOR_CYAN, 100); } if (!btn->stable_state) { // 第二次松开 -> 双击 btn->callback(EVT_PRESS_UP); if (btn->tick_cnt < LONG_PRESS_TICKS) { btn->callback(EVT_DOUBLE_CLICK); } else { // 单击后长按 btn->callback(EVT_SINGLE_LONG_PRESS); } btn->click_count = 0; btn->state = 0; } break; default: btn->state = 0; btn->click_count = 0; break; } } static bool read_button_pin(void) { // HAL_GPIO_ReadPin == GPIO_PIN_SET(1) 时,表示松开 // return pin_get_valid(&g_cfg_board->key_switch_mode); return pin_get_valid(&key_switch); } //添加自定义初始化 void _work_button(void *arg) { button_scan(&btn); os_work_later(10); } void button_work_init() { pin_cfg_input(&key_switch); // pin_cfg_output(&boot_switch); // gpio_to_high_z(&boot_switch); button_init(&btn, read_button_pin, my_button_handler); os_work_create(&work_handler_button, "work-button", _work_button, NULL, OS_PRIORITY_NORMAL); os_work_submit(default_os_work_q_hdl, &work_handler_button, 10); } void boot_set(uint8_t value) { // 设置按键为高阻态,防止冲突 gpio_to_high_z(&key_switch); os_work_suspend(&work_handler_button); pin_cfg_output(&boot_switch); pin_set_valid(&boot_switch, value); } void boot_set_high_z(void) { gpio_to_high_z(&boot_switch); //重新初始化按键 pin_cfg_input(&key_switch); os_work_resume(&work_handler_button,10); // os_work_later(10); } void key_test(void) { boot_set(0); os_thread_sleep(5000); boot_set_high_z(); } void boot_set_2(uint8_t value) { pin_cfg_output(&boot_switch); pin_set_valid(&boot_switch, value); os_work_suspend(&work_handler_button); } void boot_set_high_z_2(void) { pin_cfg_input(&key_switch); os_work_resume(&work_handler_button,10); } bool key_get_status(void) { return pin_get_valid(&key_switch); }