wch-code/ch32v307_mp3_dac/User/bsp/bsp_key.c
2024-05-05 22:27:52 +08:00

165 lines
5.4 KiB
C

#include "bsp_key.h"
#include "debug.h"
void BSP_KEY_SCAN_TIM_IRQHANDLER(void) __attribute__((interrupt("WCH-Interrupt-fast")));
typedef enum {
bsp_key_value_none = 0,
bsp_key_value_next = 0x01,
bsp_key_value_pause = 0x02,
bsp_key_value_prev = 0x04,
bsp_key_value_mode = 0x08,
} bsp_key_value_e;
struct {
volatile bsp_key_value_e pressed_key;
volatile bsp_key_value_e last_key;
volatile uint8_t long_press_cnt;
volatile uint8_t long_pressed;
volatile bsp_key_event_e key_event;
} bsp_key_status = {
.pressed_key = bsp_key_value_none,
.last_key = bsp_key_value_none,
.long_press_cnt = 0,
.long_pressed = 0,
.key_event = bsp_key_none
};
void bsp_key_init(void)
{
BSP_KEY_SCAN_TIM_RCC_ENABLE();
/* 配置用于定时扫描按键的定时器 */
TIM_TimeBaseInitTypeDef TimeBase_InitStruct;
TimeBase_InitStruct.TIM_Prescaler = SystemCoreClock / 1000000 - 1;
TimeBase_InitStruct.TIM_Period = 10000 - 1; //溢出周期为10ms
TimeBase_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TimeBase_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TimeBase_InitStruct.TIM_RepetitionCounter = 0x0000;
TIM_TimeBaseInit(BSP_KEY_SCAN_TIM, &TimeBase_InitStruct); //初始化定时器2的时基作为DAC转换触发器
TIM_ITConfig(BSP_KEY_SCAN_TIM, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = BSP_KEY_SCAN_TIM_IRQN; //使能定时器中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
RCC_APB2PeriphClockCmd(BSP_KEY_NEXT_PORT_RCC | BSP_KEY_PAUSE_PORT_RCC | BSP_KEY_PREV_PORT_RCC |
BSP_KEY_MODE_PORT_RCC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = BSP_KEY_NEXT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(BSP_KEY_NEXT_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BSP_KEY_PAUSE_PIN;
GPIO_Init(BSP_KEY_PAUSE_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BSP_KEY_PREV_PIN;
GPIO_Init(BSP_KEY_PREV_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BSP_KEY_MODE_PIN;
GPIO_Init(BSP_KEY_MODE_PORT, &GPIO_InitStructure);
TIM_Cmd(BSP_KEY_SCAN_TIM, ENABLE); //使能定时器
}
bsp_key_value_e bsp_key_scan(void)
{
if (GPIO_ReadInputDataBit(BSP_KEY_NEXT_PORT, BSP_KEY_NEXT_PIN) == Bit_RESET) {
return bsp_key_value_next;
} else if (GPIO_ReadInputDataBit(BSP_KEY_PAUSE_PORT, BSP_KEY_PAUSE_PIN) == Bit_RESET) {
return bsp_key_value_pause;
} else if (GPIO_ReadInputDataBit(BSP_KEY_PREV_PORT, BSP_KEY_PREV_PIN) == Bit_RESET) {
return bsp_key_value_prev;
} else if (GPIO_ReadInputDataBit(BSP_KEY_MODE_PORT, BSP_KEY_MODE_PIN) == Bit_RESET){
return bsp_key_value_mode;
} else {
return bsp_key_value_none;
}
}
void BSP_KEY_SCAN_TIM_IRQHANDLER(void)
{
if (TIM_GetITStatus(BSP_KEY_SCAN_TIM, TIM_IT_Update) != RESET) //检查定时器更新中断发生与否
{
bsp_key_status.pressed_key = bsp_key_scan(); //记录按键值
if (bsp_key_status.pressed_key == bsp_key_value_none && !bsp_key_status.last_key) { //按键完全抬起之后
bsp_key_status.long_pressed = 0;
}
if (bsp_key_status.pressed_key) { //如果按键按下了
if (!bsp_key_status.long_pressed) { //当前还未触发长按事件
bsp_key_status.long_press_cnt ++;
if (bsp_key_status.long_press_cnt >= 50) {
bsp_key_status.key_event = (bsp_key_event_e)(bsp_key_status.pressed_key << 4); //长按按键事件
bsp_key_status.long_pressed = 1;
}
}
} else {
bsp_key_status.long_press_cnt = 0;
}
if (bsp_key_status.last_key != bsp_key_value_none && //按键抬起边沿 并且没有触发过长按事件
(bsp_key_status.pressed_key == bsp_key_value_none) && !bsp_key_status.long_pressed) {
bsp_key_status.key_event = (bsp_key_event_e)bsp_key_status.last_key; //短按按键事件
}
bsp_key_status.last_key = bsp_key_status.pressed_key; //按下时不记录按键状态
TIM_ClearITPendingBit(BSP_KEY_SCAN_TIM, TIM_IT_Update); //清除定时器更新中断标志
}
}
bsp_key_event_e bsp_key_get_event(void)
{
bsp_key_event_e event_ret = bsp_key_none;
if (bsp_key_status.key_event != bsp_key_none) {
event_ret = bsp_key_status.key_event;
bsp_key_status.key_event = bsp_key_none;
}
return event_ret;
}
const char *bsp_key_get_event_string(bsp_key_event_e key_event)
{
switch (key_event)
{
case bsp_key_none:
return "bsp_key_none";
case bsp_key_next_short:
return "bsp_key_next_short";
case bsp_key_pause_short:
return "bsp_key_pause_short";
case bsp_key_mode_short:
return "bsp_key_mode_short";
case bsp_key_next_long:
return "bsp_key_next_long";
case bsp_key_pause_long:
return "bsp_key_pause_long";
case bsp_key_prev_long:
return "bsp_key_prev_long";
case bsp_key_mode_long:
return "bsp_key_mode_long";
default:
LOG_W("unknown key event id: %d", key_event);
return "unknown";
}
}