key.c
/** **************************************************************************************************** * @file key.c * @author Kyro Qu * @brief按键驱动代码 * 实验平台: STM32G431RB开发板 **************************************************************************************************** */#include "key.h"#include "lcd.h"#include "stdio.h"typedef struct{GPIO_TypeDef *Key_Port;uint16_t Key_Pin;}Key_GPIO_t;static Key_GPIO_t g_KeyList[] ={{ KEY_B1_GPIO_Port, KEY_B1_Pin },{ KEY_B2_GPIO_Port, KEY_B2_Pin },{ KEY_B3_GPIO_Port, KEY_B3_Pin },{ KEY_B4_GPIO_Port, KEY_B4_Pin }/* add other KEY, ... */};#define KEY_NUM_MAX(sizeof(g_KeyList)/sizeof(g_KeyList[0]))typedef enum{KEY_RELEASE =0, /* 释放松开 */KEY_CONFIRM, /* 消抖确认 */KEY_SHORT_PRESS, /* 短按 */KEY_LONG_PRESS, /* 长按 */}KEY_STATE;#define CONFIRM_TIME10 /* 消抖时间 ms */#define LONG_PRESS_TIME2000 /* 长按时间窗 ms */typedef struct{KEY_STATE keyState; /* 按键状态 */uint32_tprvTime; /* 按键时间 */}Key_Info_t;static Key_Info_t g_Key_Info[KEY_NUM_MAX];/** * @brief 扫描单个按键不同状态函数 * @param 按键端口号 * @retval键值 */static uint8_t keyScan(uint8_t keyIndex){uint8_t keyPress;keyPress=HAL_GPIO_ReadPin(g_KeyList[keyIndex].Key_Port,g_KeyList[keyIndex].Key_Pin);#if !ElECTRIC_LEVELkeyPress=!keyPress;#endifswitch (g_Key_Info[keyIndex].keyState)/* 按键状态机 */{ case KEY_RELEASE :if(keyPress )/* 如果按下 */{g_Key_Info[keyIndex].keyState = KEY_CONFIRM;g_Key_Info[keyIndex].prvTime = HAL_GetTick();/* 获取按下起始时间 */ }break;case KEY_CONFIRM :if(keyPress ){if(HAL_GetTick()-g_Key_Info[keyIndex].prvTime>CONFIRM_TIME ){g_Key_Info[keyIndex].keyState = KEY_SHORT_PRESS;}}else{g_Key_Info[keyIndex].keyState = KEY_RELEASE;}break;case KEY_SHORT_PRESS :if(keyPress ){if(HAL_GetTick()-g_Key_Info[keyIndex].prvTime>LONG_PRESS_TIME ){g_Key_Info[keyIndex].keyState = KEY_LONG_PRESS;}}else/* 如果松开 */ {g_Key_Info[keyIndex].keyState = KEY_RELEASE;return (keyIndex+0x01);/* 返回短按对应码值0x01 0x02 0x03 .....*/}break;case KEY_LONG_PRESS :if(!keyPress )/* 如果松开 */ {g_Key_Info[keyIndex].keyState = KEY_RELEASE;return (keyIndex+0x81);/* 返回短按对应码值0x81 0x82 0x83 .....*/} break;default:g_Key_Info[keyIndex].keyState = KEY_RELEASE;}return 0;}/** * @brief扫描单个按键 按键的码值 * @param无 * @retval 键值 */uint8_t GetKeyVal(void){uint8_tres = 0; for(uint8_t i=0;i<KEY_NUM_MAX;i++){res = keyScan(i);/* 临时保存键值 */if(res!= 0)/* 返回键值不为0,则跳出 */{break;}}return res;/* 返回键值 */}/** * @brief按键处理函数 * @param无 * @retval 无 */void KeyHandler(void){uint8_t KEY_STATE;KEY_STATE=GetKeyVal();switch(KEY_STATE){case B1_SHORT_PRESS:break;case B1_LONG_PRESS:break;case B2_SHORT_PRESS:break;case B2_LONG_PRESS:break;case B3_SHORT_PRESS:break;case B3_LONG_PRESS:break;case B4_SHORT_PRESS:break;case B4_LONG_PRESS:break;}}
key.h
/** **************************************************************************************************** * @file key.h * @author Kyro Qu * @brief按键驱动代码 * 实验平台: STM32G431RB开发板 **************************************************************************************************** */#ifndef __KEY_H#define __KEY_H#include "main.h"//按键另一端口的电平1为高电平 0为低电平#define ElECTRIC_LEVEL 0/* 键值 */#define B1_SHORT_PRESS 0x01#define B1_LONG_PRESS0x81#define B2_SHORT_PRESS 0x02#define B2_LONG_PRESS0x82#define B3_SHORT_PRESS 0x03#define B3_LONG_PRESS0x83#define B4_SHORT_PRESS 0x04#define B4_LONG_PRESS0x84uint8_t keyScan(uint8_t mode);/* 按键扫描函数 */uint8_t GetKeyVal(void);void KeyHandler(void);#endif