战舰开发板V4——按键输入

📅 2026/7/30 22:48:16 👁️ 阅读次数 📝 编程学习
战舰开发板V4——按键输入

战舰开发板V4——按键输入

image-20260730191128890

image-20260730195246471

#include "Key.h"
#include "Delay.h"/*** @brief  按键初始化函数* @param  无* @retval 无*/
void Key_Init(void)
{GPIO_InitTypeDef GPIO_Init_Struct;KEY0_GPIO_CLK_ENABLE();                            /* KEY0时钟使能 */KEY1_GPIO_CLK_ENABLE();                            /* KEY1时钟使能 */	KEY2_GPIO_CLK_ENABLE();                            /* KEY2时钟使能 */	WKUP_GPIO_CLK_ENABLE();                            /* WKUP时钟使能 */GPIO_Init_Struct.Pin = KEY0_GPIO_PIN;              /* KEY0引脚 */GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */HAL_GPIO_Init(KEY0_GPIO_PORT, &GPIO_Init_Struct);  /* KEY0引脚模式设置,上拉输入 */GPIO_Init_Struct.Pin = KEY1_GPIO_PIN;              /* KEY1引脚 */GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */HAL_GPIO_Init(KEY1_GPIO_PORT, &GPIO_Init_Struct);  /* KEY1引脚模式设置,上拉输入 */GPIO_Init_Struct.Pin = KEY2_GPIO_PIN;              /* KEY2引脚 */GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */GPIO_Init_Struct.Pull = GPIO_PULLUP;               /* 上拉 */GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */HAL_GPIO_Init(KEY2_GPIO_PORT, &GPIO_Init_Struct);  /* KEY2引脚模式设置,上拉输入 */GPIO_Init_Struct.Pin = WKUP_GPIO_PIN;              /* WKUP引脚 */GPIO_Init_Struct.Mode = GPIO_MODE_INPUT;           /* 输入 */GPIO_Init_Struct.Pull = GPIO_PULLDOWN;             /* 下拉 */GPIO_Init_Struct.Speed = GPIO_SPEED_FREQ_HIGH;     /* 高速 */HAL_GPIO_Init(WKUP_GPIO_PORT, &GPIO_Init_Struct);  /* WKUP引脚模式设置,下拉输入 */
}/*** @brief  按键扫描函数* @note   该函数有响应优先级(同时按下多个按键):WK_UP > KEY2 > KEY1 > KEY0 !!* @param  mode:0 / 1,具体含义如下:*	 @arg  0,不支持连续按(当按键按下不放时,只有第一次调用会返回值,*         必须松开以后,再次按下才会返回其他键值)*   @arg  1,支持连续按(当按键按下不放时,每次调用该函数都会返回键值)* @retval 键值,定义如下:*         KEY0_PRES, 1, KEY0按下*         KEY1_PRES, 2, KEY1按下*         KEY2_PRES, 3, KEY2按下*         WKUP_PRES, 4, WKUP按下*/
uint8_t Key_Scan(uint8_t mode)
{static uint8_t Key_Up = 1;                                      /* 按键按松开标志 */uint8_t KeyVal = 0;if(mode)  Key_Up = 1;                                           /* 支持连按 */if(Key_Up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1)/* 按键松开标志为1,且有任意一个按键按下了  */{delay_ms(10);                                               /* 去抖动 */Key_Up = 0;if(KEY0 == 0)  KeyVal = KEY0_PRES;if(KEY1 == 0)  KeyVal = KEY1_PRES;	if(KEY2 == 0)  KeyVal = KEY2_PRES;if(WK_UP == 1) KeyVal = WKUP_PRES;}else if(KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)      /* 没有任何按键按下, 标记按键松开 */{Key_Up = 1;}return KeyVal;                                                  /* 返回键值 */}
#ifndef __KEY_H
#define __KEY_H#include "main.h"/* 定义 引脚 */#define KEY0_GPIO_PORT               GPIOE
#define KEY0_GPIO_PIN                GPIO_PIN_4
#define KEY0_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */#define KEY1_GPIO_PORT               GPIOE
#define KEY1_GPIO_PIN                GPIO_PIN_3
#define KEY1_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */#define KEY2_GPIO_PORT               GPIOE
#define KEY2_GPIO_PIN                GPIO_PIN_2
#define KEY2_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */#define WKUP_GPIO_PORT               GPIOA
#define WKUP_GPIO_PIN                GPIO_PIN_0
#define WKUP_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */#define KEY0          HAL_GPIO_ReadPin(KEY0_GPIO_PORT, KEY0_GPIO_PIN)   /* 读取KEY0引脚 */
#define KEY1          HAL_GPIO_ReadPin(KEY1_GPIO_PORT, KEY1_GPIO_PIN)   /* 读取KEY1引脚 */
#define KEY2          HAL_GPIO_ReadPin(KEY2_GPIO_PORT, KEY2_GPIO_PIN)   /* 读取KEY2引脚 */
#define WK_UP         HAL_GPIO_ReadPin(WKUP_GPIO_PORT, WKUP_GPIO_PIN)   /* 读取WKUP引脚 */#define KEY0_PRES     1          /* KEY0按下 */
#define KEY1_PRES     2          /* KEY1按下 */
#define KEY2_PRES     3          /* KEY2按下 */
#define WKUP_PRES     4          /* KEY_UP按下(即WK_UP) */void Key_Init(void);             /* 按键初始化函数 */
uint8_t Key_Scan(uint8_t mode);  /* 按键扫描函数 */#endif
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)   //无限主循环,程序主体在这里循环执行
{/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///循环内部,所有业务逻辑写这里Key = Key_Scan(0);                /* 得到键值 */if(Key){switch(Key){case WKUP_PRES:           /* 控制蜂鸣器 */BEEP_TOGGLE();        /* BEEP 状态取反 */break;case KEY2_PRES:           /* 控制LED0(RED)翻转 */LED0_TOGGLE();        /* LED0 状态取反 */break;case KEY1_PRES:           /* 控制LED1(GREEN)翻转 */LED1_TOGGLE();        /* LED1 状态取反 */break;case KEY0_PRES:           /* 同时控制LED0,LED1翻转 */LED0_TOGGLE();        /* LED0 状态取反 */LED1_TOGGLE();        /* LED1 状态取反 */break;default: break;}	}	else{delay_ms(10);}
}