使用的是正点原子的精英版,单片机是STM32F103ZET6,本例程实现实现KEY UP控制蜂鸣器响停,KEY1控制LED1翻转,KEY0控制LED0翻转。先看原理图
主要使用到的是开发板上面的KEY_UP, KEY0, KEY1 三个按键分别对应的是PA0,PE4, PE3三个IO口,根据电路图可以知道 KEY_UP是接到高电平3.3V上面,KEY0, KEY1接到GND上面。当KEY_UP按下时PA0就会读取到高电平,所以为了读取到准确的高低电平,我们需要将PA0设置为下拉输入,KEY0, KEY1与KEY_UP相反即可。
下面我们开始操作,复制黏贴上一节蜂鸣器的代码,参考上一章代码,打开图形化配置将PB8进行如下配置
按照上图进行配置,KEY0与KEY1一样配置即可(标签不一样),其他的都不需要更改,点击上面齿轮生成代码,在BSP文件下新建KEY文件里面新建key.c与key.h工程,和上章一样将路径添加进去即可,
好的,接下来在key.c中添加以下代码
#include "key.h"
/**
* @brief 按键扫描函数
* @note 该函数有响应优先级(同时按下多个按键): WK_UP > KEY1 > KEY0!!
* @param mode:0 / 1, 具体含义如下:
* @arg 0, 不支持连续按(当按键按下不放时,只有第一次调用会返回键值,
* 必须松开以后,再次接下才会返回其他键值)
* @arg 1, 支持连续按(当按键按下不放时,每次调用该函数都会返回键值)
* @retval 键值,定义如下:
* KEY0_PRES, 1, KEY0按下
* KEY1_PRES, 2, KEY1按下
* WKUP_PRES, 3, 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 || WK_UP == 1)) /* 按键松开标志为1,且有任意一个按键按下了 */
{
HAL_Delay(10); /* 去抖动 */
key_up = 0; /* 模式:不支持连续按 */
if (KEY0 == 0) keyval = KEY0_PRES;//当检测到KEY0按下时,返回值为KEY0_PRES,也就是1
if (KEY1 == 0) keyval = KEY1_PRES;//当检测到KEY1按下时,返回值为KEY1_PRES,也就是2
if (WK_UP == 1) keyval = WKUP_PRES;//当检测到WK_UP按下时,返回值为WKUP_PRES,也就是3
}
else if (KEY0 == 1 && KEY1 == 1 && WK_UP == 0) /* 没有任何按键按下,标记按键松开 */
{
key_up = 1; /* 模式:支持连接 */
}
return keyval; /* 返回键值 */
}
在key.h中添加以下代码
#ifndef BSP_KEY_KEY_H_
#define BSP_KEY_KEY_H_
#include "main.h"
#define KEY0 HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) /* 读取KEY0引脚 */
#define KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) /* 读取KEY10引脚 */
#define WK_UP HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) /* 读取WKUP引脚 */
#define KEY0_PRES 1 /* KEY0按下 */
#define KEY1_PRES 2 /* KEY1按下 */
#define WKUP_PRES 3 /* KEY_UP按下(即WK_UP) */
uint8_t key_scan(uint8_t mode); /* 按键扫描函数 */
#endif /* BSP_KEY_KEY_H_ */
在main.c中添加以下代码
/* USER CODE BEGIN Includes */
#include "led.h"
#include "beep.h"
#include "key.h"
/* USER CODE END Includes */
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t key=0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
key=key_scan(0);//模式,不支持连续按
if(key==KEY0_PRES)/* KEY0按下 */
{
LED0_TOGGLE();//电平翻转
}
else if(key==KEY1_PRES)/* KEY1按下 */
{
LED1_TOGGLE();//电平翻转
}
else if(key==WKUP_PRES)/* KEY_UP按下(即WK_UP) */
{
BEEP_TOGGLE();//电平翻转
}
HAL_Delay(10);//消抖
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
完成之后编译下载,即可实现KEY UP控制蜂鸣器响停,KEY1控制LED1翻转,KEY0控制LED0翻转。