蓝桥杯STM32G431RBT6学习——按键
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
蓝桥杯STM32G431RBT6学习——按键
前言
按键同样为每年的必考考点国信长天开发板中的按键电路如下
芯片的PA0、PB0、PB1、PB2作为按键输入引脚并采用外部上拉连接当对应引脚检测到低电平时即按键被按下。
STM32CubeMX配置
时钟配置不变将以上引脚配置为输入模式并设置其上拉模式。
Keil代码编写
关于按键的常用API如下
读取IO口电平
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
参数1IO口所在组;
参数2IO口引脚号
整体控制
关于按键的使用主要使用的方式有单击、长按众所周知硬件按键按下时都会产生一定的抖动因此需要延时消抖处理。为了程序重复执行可以在代码算法上将其分为两个状态进行判断即按键按下与按键松开。
(1单击
对于单击而言只需要区分一次按键按下松开即可在程序中设置一个标志位用于判断按键的状态(初始化为0当按键按下时判断读取电平是否为低电平同时标志位需要为0方才认为按键按下并将标志位置1;当按键松开时判断读取电平为高电平同时标志位需要为1(曾经按下过方才认为按键松开了并将标志位置0。
代码如下
/****************
函数功能按键单击读取函数
函数参数无
函数返回值按下的按键键值KeyB1~KeyB4->a~d
****************/
uchar key_Scan(void)
{
static uchar K1_flag,K2_flag,K3_flag,K4_flag;
if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
{
HAL_Delay(5);
if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
{
K1_flag = 1;
return 'a';
}
}
else if(KeyB1 == GPIO_PIN_SET && K1_flag == 1)
K1_flag = 0;
if(KeyB2 == GPIO_PIN_RESET && K2_flag == 0)
{
HAL_Delay(5);
if(KeyB2 == GPIO_PIN_RESET && K2_flag == 0)
{
K2_flag = 1;
return 'b';
}
}
else if(KeyB2 == GPIO_PIN_SET && K2_flag == 1)
K2_flag = 0;
if(KeyB3 == GPIO_PIN_RESET && K3_flag == 0)
{
HAL_Delay(5);
if(KeyB3 == GPIO_PIN_RESET && K3_flag == 0)
{
K3_flag = 1;
return 'c';
}
}
else if(KeyB3 == GPIO_PIN_SET && K3_flag == 1)
K3_flag = 0;
if(KeyB4 == GPIO_PIN_RESET && K4_flag == 0)
{
HAL_Delay(5);
if(KeyB4 == GPIO_PIN_RESET && K4_flag == 0)
{
K4_flag = 1;
return 'd';
}
}
else if(KeyB4 == GPIO_PIN_SET && K4_flag == 1)
K4_flag = 0;
return 0;
}
通过读取函数返回值即可判断按键是否按下。
(2长按
对于长按而言字面意思就是按下按键达到一段时间后才会触发按键的功能因此毫无疑问最简单粗暴的方法就是当按键按下时用延时进行阻塞一段时间后再检测按键是否还是按下即可分辨是否属于长按。
代码如下
if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
{
HAL_Delay(5);
if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
{
HAL_Delay(500);
if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
{
K1_flag = 1;
return 'a';
}
}
}
但是这种方法存在弊端1、严重影响系统运行一般长按的时间都较长(500ms以上对于单片机而言如此长的时间不干活是严重的资源浪费;2、难以实现多种按键并存当一个按键既需要长按又需要短按的时候这种方法就会很尴尬。
解决方法后续使用定时器进行辅助按键功能的实现。