Files
DTU-LCD/Drivers/BSP/KEY/key.c
2026-01-24 20:03:14 +08:00

148 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @文件 key.c
* @作者 阜阳师范大学物电学院
* @版本 V0.1
* @日期 2026-01-15
* @简介 按键驱动 - 基于 MultiButton 的高可移植性实现
* @说明
*
****
*/
#include "key.h"
// 按键配置结构体
typedef struct {
uint16_t pin; // GPIO引脚
GPIO_TypeDef* port; // GPIO端口
KEY_TYPE key_type; // 按键ID
} KeyConfig_t;
/*
*******************详细引脚映射*****************************
| 按键名称 | 端口 | 引脚 | 位定义 | 功能说明 |
|---------|------|------|--------|----------|
| KEY_ENTER | GPIOB | PB15 | KEY_ENTER_BIT | 确认键 |
| KEY_UP | GPIOD | PD11 | KEY_UP_BIT | 上键 |
| KEY_DOWN | GPIOD | PD10 | KET_DOWN_BIT | 下键 |
| KEY_LEFT | GPIOD | PD13 | KET_LEFT_BIT | 左键 |
| KEY_RIGHT | GPIOD | PD8 | KET_RIGHT_BIT | 右键 |
| KEY_ESC | GPIOD | PD12 | KET_ESC_BIT | 取消键 |
| KEY_ADD | GPIOD | PD14 | KET_ADD_BIT | 加键 |
| KEY_DEC | GPIOD | PD9 | KET_DEC_BIT | 减键 |
| KEY_RESET | GPIOD | PD15 | KET_RESET_BIT | 复位键 |
***************************************************************
*/
// 按键配置表
static const KeyConfig_t key_configs[] = {
{15, GPIOB, KEY_ENTER},
{11, GPIOD, KEY_UP},
{10, GPIOD, KEY_DOWN},
{13, GPIOD, KEY_LEFT},
{8, GPIOD, KEY_RIGHT},
{12, GPIOD, KEY_ESC},
{14, GPIOD, KEY_ADD},
{9, GPIOD, KEY_DEC},
{15, GPIOD, KEY_RESET},
};
#define KEY_COUNT (sizeof(key_configs) / sizeof(key_configs[0]))
// 按键句柄数组
static Button btn_handles[KEY_COUNT];
// 业务逻辑回调函数指针由main.c注册
static KeyCallback key_callback = NULL;
/**
* @brief 读取按键GPIO电平
* @param button_id 按键ID
* @retval 0:按下, 1:释放
*/
static uint8_t button_read_level(uint8_t button_id)
{
uint16_t pin_bit = HAL_GPIO_ReadPin(key_configs[button_id].port, key_configs[button_id].pin);
return pin_bit;
}
/**
* @brief 统一的按键回调函数(内部使用,调用业务逻辑回调)
* @param btn 按键句柄指针
*/
static void button_callback(Button* btn)
{
if (btn != NULL && key_callback != NULL)
{
// 通过button_id获取对应的按键类型
uint8_t button_id = btn->button_id;
if (button_id < KEY_COUNT)
{
// 调用业务逻辑层注册的回调函数
key_callback(key_configs[button_id].key_type);
}
}
}
/**
* @brief 注册按键回调函数(供业务逻辑层调用)
* @param callback 回调函数指针
*/
void Key_RegisterCallback(KeyCallback callback)
{
key_callback = callback;
}
/**
* @brief 使能GPIO时钟
* @param port: GPIO端口
* @retval 无
* @note 使用switch-case结构代码更简洁清晰支持所有GPIO端口A-G
*/
static void KEY_GPIO_ClockEnable(GPIO_TypeDef *port)
{
switch ((uint32_t)port) {
case (uint32_t)GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break;
case (uint32_t)GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break;
case (uint32_t)GPIOC: __HAL_RCC_GPIOC_CLK_ENABLE(); break;
case (uint32_t)GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break;
case (uint32_t)GPIOE: __HAL_RCC_GPIOE_CLK_ENABLE(); break;
case (uint32_t)GPIOF: __HAL_RCC_GPIOF_CLK_ENABLE(); break;
case (uint32_t)GPIOG: __HAL_RCC_GPIOG_CLK_ENABLE(); break;
default: break;
}
}
/**************************************************************************************
* FunctionName : Key_Init()
* Description : 按键硬件初始化使用MultiButton库
* EntryParameter : none
* ReturnValue : none
**************************************************************************************/
void Key_Init(void)
{
GPIO_InitTypeDef gpio_init_struct;
// 统一配置GPIO参数
gpio_init_struct.Mode = GPIO_MODE_INPUT;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_HIGH;
// 批量初始化GPIO
for (uint8_t i = 0; i < KEY_COUNT; i++)
{
/* 使能对应GPIO时钟 */
KEY_GPIO_ClockEnable(key_configs[i].port);
// 配置并初始化引脚
gpio_init_struct.Pin = key_configs[i].pin;
HAL_GPIO_Init(key_configs[i].port, &gpio_init_struct);
}
// 批量初始化MultiButton按键active_level=0表示低电平有效
for (uint8_t button_id = 0; button_id < KEY_COUNT; button_id++)
{
button_init(&btn_handles[button_id], button_read_level, 0, button_id);
button_attach(&btn_handles[button_id], BTN_SINGLE_CLICK, button_callback);
button_start(&btn_handles[button_id]);
}
}