#include "bsp_key.h" #include #include "main.h" #include "led_control.h" typedef struct { uint8_t is_pressed_before; uint8_t is_long_pressed; uint32_t long_press_count; volatile bsp_key_event_type_e event; } bsp_key_status_t; static bsp_key_status_t key_in_status[BSP_KEY_COUNT]; static bsp_key_number_e bsp_key_read(void) { bsp_key_number_e key_in = bsp_key_none; if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key1; } if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key2; } if (HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key3; } if (HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key4; } if (HAL_GPIO_ReadPin(KEY5_GPIO_Port, KEY5_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key5; } if (HAL_GPIO_ReadPin(KEY6_GPIO_Port, KEY6_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key6; } if (HAL_GPIO_ReadPin(KEY7_GPIO_Port, KEY7_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key7; } if (HAL_GPIO_ReadPin(KEY8_GPIO_Port, KEY8_Pin) == BSP_KEY_PRESSED_GPIO_LEVEL) { key_in |= bsp_key8; } return key_in; } void bsp_key_process(void) { uint8_t command[BSP_KEY_COUNT]; bsp_key_number_e key_in = bsp_key_read(); //读取按键值 for (uint8_t key_index = 0; key_index < BSP_KEY_COUNT; key_index ++) { uint8_t is_pressed = key_in & 1u << key_index ? 1 : 0; //第key_index个按键是否被按下 /* 按键抬起状态 */ if(!is_pressed && !key_in_status[key_index].is_pressed_before) { //本次没有按下 上次也没有按下 key_in_status[key_index].is_long_pressed = 0; key_in_status[key_index].long_press_count = 0; //复位长按状态 } /* 按键按下状态 */ if (is_pressed) { //按键处于被按下的状态 if (!key_in_status[key_index].is_long_pressed) { //如果还未触发长按事件 key_in_status[key_index].long_press_count ++; //记录长按时间 if (key_in_status[key_index].long_press_count > //长按时间超过阈值 BSP_KEY_LONG_PRESS_THRESHOLD_MS / BSP_KEY_SCAN_INTERVAL_MS) { key_in_status[key_index].is_long_pressed = 1; //记录产生了长按事件 memset(command, bsp_led_command_off, sizeof(command)); command[key_index] = bsp_led_command_on; //长按事件-关闭除此LED之外的所有LED led_control_command_send_from_isr(command); } } } /* 按键抬起边沿 */ if (!is_pressed && key_in_status[key_index].is_pressed_before && !key_in_status[key_index].is_long_pressed) { //本次没有按下 但上次按下了 且未触发长按事件 memset(command, bsp_led_command_none, sizeof(command)); command[key_index] = bsp_led_command_toggle; //短按事件-翻转LED led_control_command_send_from_isr(command); } key_in_status[key_index].is_pressed_before = is_pressed; //记录上次按下的状态 } } void bsp_key_get_event(bsp_key_number_e *key, bsp_key_event_type_e *event) { *key = bsp_key_none; *event = bsp_key_event_none; for (uint8_t key_index = 0; key_index < BSP_KEY_COUNT; key_index ++) { //第key_index个按键是否被按下 if (key_in_status[key_index].event != bsp_key_event_none) { *key = 1u << key_index; *event = key_in_status[key_index].event; key_in_status[key_index].event = bsp_key_event_none; return; } } } void bsp_key_scan_start(void) { HAL_TIM_Base_Start_IT(&BSP_KEY_SCAN_TIM); }