stm32-code/stm32f072_usb_custom_hid/User/Src/bsp_key.c

112 lines
3.7 KiB
C

#include "bsp_key.h"
#include <string.h>
#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);
}