引言:我们经常在使用按键功能时发现,每按一次按键,会触发好几次对应的按键功能,因此我们需要方法去除这种由于按键抖动一起的错误–即为按键去抖动。本文章介绍一种简单的按键去抖动方法。
使用软件工具
软件:stm32cubemx ,keil uVision5,串口接收软件(我使用的是KoalaSerialPort),VScode.
硬件:stm32f103zet6,ST-link下载器,数据线.
STM32CUBEMX相关配置
打开stm32cubemx,点击红圈部分
查找芯片型号,选择对应芯片
进行如下初始调整
调节时钟树
打开串口1方便验证防抖动的效果
接下来我们来查看我使用的这款单片机的按键部分的电路图
举例选用key0和key1来展示效果。
将对应的PA0和PE4引脚的gpio_output打开
便于检测判断,将PA0输出低电位,将PE5输出高电位。
给项目命名,更改IDE为MDK-ARM。
按如下图进行调整,按GENERATE CODE产生代码
项目初始化完成。
代码编写及调试过程
在usart.c中加入串口初始化(便于直接使用printf进行输出)
#include <stdio.h>
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
在main.c中也需要加入#include <stdio.h>。
在while(1)循环中加入
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==GPIO_PIN_RESET)
printf("KEY1=1");
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)
{
HAL_Delay(20);
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_SET)
printf("KEY0=1");
}
按下图设置printf必须项
进行编译,连接单片机后烧写。连接串口1和电脑。打开串口助手。
可以观察到没有防抖动的KEY1,在按下一次后,产生了多次打印,而KEY0由于有了防抖动,每按一次只打印一次。
即可验证防抖动程序有效。
实现所有按键都防抖动
在gpio设置中加入其他几个按键对应的引脚,调节输出的电平高低,有需要可以对引脚进行命名。
在vscode中编写代码,我采用编写key.c和key.h来完成该功能。代码如下
key.h中较为简单
#ifndef KEY_
#define KEY_
int KEY_scan(void);
#endif
key.c中采用宏定义简化代码,用函数的返回值结合主函数中的switch完成该功能。
#include "stdio.h"
#include "gpio.h"
#include "main.h"
#define KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)
#define KEY2 HAL_GPIO_ReadPin(KEY2_GPIO_Port,KEY2_Pin)
#define KEY3 HAL_GPIO_ReadPin(KEY3_GPIO_Port,KEY3_Pin)
#define GPIO_PIN_RESET 0
#define GPIO_PIN_SET 1
int KEY_scan(*void*);
{
if(KEY0==0&KEY1==1&KEY2==1&KEY3==1)
{
HAL_Delay(20);
if(KEY0==1)
return 0;
if(KEY1==0)
return 1;
if(KEY2==0)
return 2;
if(KEY3==0)
return 3;
}
return 4;
}
主函数在while(1)中加入switch函数如下
switch(KEY_scan())
{
case 0 :
{
printf("KEY0=1");
break;
}
case 1 :
{
printf("KEY1=1");
break;
}
case 2 :
{
printf("KEY2=1");
break;
}
case 3 :
{
printf("KEY3=1");
break;
}
default: break;
}
即可完成对单片机(stmf103zet6)上的按键全部完成消抖。
我是一个刚刚入门的新手,有问题希望各位大佬指正,感谢。
|