前言
板载的四个按键分别接了PB0~PB2、PA0这四个引脚,并且按键一端外接了上拉电阻,另一端接到gnd,当按键按下时单片机引脚的电平会被拉低。
STM32CubeMX配置
首先要将PB0~PB2、PA0配置为上拉输入模式。
鼠标左击要配置的引脚选择引脚工作模式为输入模式。
将PB0~PB2、PA0配置为上拉输入模式。
配置完成后点击“GENERATE COOE”等待软件更新工程配置。
keil5程序
按键功能有长按键和短按键的效果,程序如下:
key.c
#include "key.h"
Key Bsp_key[4] = {0};
/*
函数功能 : 按键扫描函数,将此函数定时执行,可识别长短按键
函数参数 : 空
返 回 值 : 空
*/
void KeyScan(void)
{
Bsp_key[0].Pin = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
Bsp_key[1].Pin = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
Bsp_key[2].Pin = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
Bsp_key[3].Pin = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(uint8_t i=0;i<4;i++)
{
switch(Bsp_key[i].State)
{
case 0:{//扫描是否有按键被按下
if(Bsp_key[i].Pin == 0)
{
Bsp_key[i].State = 1;
}
}break;
case 1:{//按键消抖
if(Bsp_key[i].Pin == 0)
{
Bsp_key[i].State = 2;//按键消抖状态
}
else
{
Bsp_key[i].State = 0;//回到按键扫描状态
}
}break;
case 2:{//记录按键触发时间长度
if(Bsp_key[i].Pin == 0)
{
Bsp_key[i].LongTim++;//如果按键还未松开则一直记录时间(可加一个判断如果按键按下时间超过某个值时强行退出)
}
else
{
Bsp_key[i].State = 3;//判断是长按键还是短按键状态
}
}break;
case 3:{//判断是长按键还是短按键
if(Bsp_key[i].LongTim >= LongTim_Data)
{
Bsp_key[i].LongFlag = 1;//长按键标志位
}
else
{
Bsp_key[i].Flag = 1;//短按键标志位
}
Bsp_key[i].LongTim = 0;//清除记录的按键按下时间值
Bsp_key[i].State = 0;//回到按键扫描状态
}break;
}
}
}
key.h
#ifndef __KEY_H
#define __KEY_H
#include "BSPSYS.h"
typedef struct
{
uint8_t Pin;//记录引脚电平
uint8_t State;//记录按键扫描的状态
uint8_t Flag;//记录短按键标志位
uint8_t LongFlag;//记录长按键标志位
uint32_t LongTim;//记录按键按下时间
}Key;
#define LongTim_Data 70//设置长按键判断时间
extern Key Bsp_key[4];
void KeyScan(void);
#endif
示例程序
#include "BspSYS.h"
/*
函数功能 : 外设初始化函数,只执行一遍
函数参数 : 空
返 回 值 : 空
*/
void setup(void)
{
LED_SetEntierty(0);
}
/*
函数功能 : 循环执行函数
函数参数 : 空
返 回 值 : 空
*/
void loop(void)
{
if(Bsp_key[0].Flag == 1)//如果是短按键点亮led1
{
LED_SetEntierty(1);
Bsp_key[0].Flag = 0;//清除按键标志位代表使用过了
}else if(Bsp_key[0].LongFlag == 1) //如果是长按键点亮led2
{
LED_SetEntierty(2);
Bsp_key[0].LongFlag = 0;//清除按键标志位代表使用过了
}
KeyScan();//按键扫描(使用定时器中断定时扫描效果更好)
HAL_Delay(10);//10ms延时
}