#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"; } }