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


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