stm32-code/stm32f0_cherryusb/Core/Src/bsp_key.c

126 lines
3.9 KiB
C

#include "bsp_key.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 key_out_gpio_value = bsp_key_none;
static uint8_t bsp_key_number_to_index(bsp_key_number_e key_number)
{
switch (key_number) {
case bsp_key1: return 0;
case bsp_key2: return 1;
case bsp_key3: return 2;
case bsp_key4: return 3;
case bsp_key5: return 4;
case bsp_key6: return 5;
case bsp_key7: return 6;
case bsp_key8: return 7;
default: return 0xFF;
}
}
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;
}
static void bsp_key_process(void)
{
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; //记录产生了长按事件
key_in_status[key_index].event = bsp_key_event_long; //产生长按事件
}
}
}
/* 按键抬起边沿 */
if (!is_pressed && key_in_status[key_index].is_pressed_before &&
!key_in_status[key_index].is_long_pressed) { //本次没有按下 但上次按下了 且未触发长按事件
key_in_status[key_index].event = bsp_key_event_press; //产生短按事件
}
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_init(void)
{
HAL_TIM_Base_Start_IT(&BSP_KEY_SCAN_TIM);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &BSP_KEY_SCAN_TIM) {
bsp_key_process();
}
}