机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理。
下面分享的方法是靠延时,不过该方法不精确,在实际操作中会有按键摁下去灯仍亮或不亮。
软件消抖 key.c代码如下
#include "KEY.h"
#include "sys.h"
#include "delay.h"
//初始化GPIO
//①定义初始化结构体
GPIO_InitTypeDef KEY_initstruct;
void KEY_init(void)
{
//打开时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //注意看硬件原理图中key的引脚在哪一个组
//调用GPIO初始化函数
KEY_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
KEY_initstruct.Pull = GPIO_PULLUP;
KEY_initstruct.Mode =GPIO_MODE_INPUT;
KEY_initstruct.Speed =GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&KEY_initstruct);
}
//②按键1扫描函数
uint8_t KEY_scan(void)
{
//检测按键是否按下
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) ==GPIO_PIN_RESET )
{
//消抖
delay_ms(10);
//再次检测按键是否按下
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) ==GPIO_PIN_RESET )
{
//如果确认是按下的状态,等待按键松开
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) ==GPIO_PIN_RESET )
//返回按键值
return 1;
}
}
//检测按键是否按下
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) ==GPIO_PIN_RESET )
{
//消抖
delay_ms(10);
//再次检测按键是否按下
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) ==GPIO_PIN_RESET )
{
//如果确认是按下的状态,等待按键松开
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) ==GPIO_PIN_RESET )
//返回按键值
return 2;
}
}
//返回原值
return 0;
}
上述代码解释,因为按键也是GPIO外设,因此和LED灯以及蜂鸣器报警一样,需要初始化,初始化内容将不再赘述,主要讲一下按键扫描的部分
①检测按键是否按下
②延时消抖
③再次检测按键是否按下
④如果确认是按下的状态,等待按键松开(这部分使用while循环不仅能等待按键松开,而且还能抑制松开抖动)
⑤返回按键值
以下问主函数main.c文件的代码
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "KEY.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
KEY_init();
led_init();
uint8_t KEY_num=0;
while(1)
{
KEY_num=KEY_scan();
if(KEY_num==1)
{
led1_toggle();
}
if(KEY_num==2)
{
led2_toggle();
}
}
}
只要返回值正确,LED灯就翻转。