前期准备:

  1. STM32CubeMX
  2. STM32RCT6核心板
  3. IDE Keil(MDK-ARM)

什么是按键消抖?

按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖

按键工作原理

esp32按键开关_esp32按键开关


这是最基本的按键电路,以KEY1为例:

3.3V流经10k电阻(限流电阻),经过按键再流入地,但是按键常态是松开的,也就是说这条路常态是是断开的,只有当按键按下时,这条路才能走通,才有电流。

那么此时我们引入一个IO口到KEY1的回路中,通过检测IO口的电平,即可知道这个回路是否有电流,即可知道按键是否按下

1.硬件消抖

硬件消抖一般是在电路硬件设计时考虑进去,提高电平的检测准确度。硬件消抖有很多种,这里我们介绍并联电容消抖法

esp32按键开关_HAL库_02


电路中按键并联了一个电容。我们知道电容两端电压不能突变

如果把电比作水,电容就像一块海绵,它无法瞬间从瘪变到膨胀,对应电路就是两端电压无法突变,因为电压会给电容充电,充满电后再放电,这个充放电过程的时间由本身参数决定,所以一般采用0.1uf电容即可

因为按键时接触抖动会产生的毛刺电压,由于电容两端电压不能突变,使得按键两端的电压平缓,可以大大提升按键精确度。

2.软件消抖

光有硬件消抖,大概率能满足大部分情况,但有时候需要更精确的场合,这时就需要软件消抖上场了,何为软件消抖,说白了就是写代码,使得按键判断精确一点

STM32CubeMX部分

1. 配置时钟

选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚

esp32按键开关_按键消抖_03


将HCLK设置为最大频率72MHz

esp32按键开关_esp32按键开关_04

2. 配置GPIO

esp32按键开关_esp32按键开关_05

  • PC4——>GPIO_Output模式
  • PB4——>GPIO_Input模式

esp32按键开关_#define_06

3. 工程生成

esp32按键开关_HAL库_07


esp32按键开关_按键消抖_08


工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成。

MDK 5部分

未消抖:
在while里写入

if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == 0)
{
	HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
}//按一次翻转一次电平

未消抖效果如图




可以看到未消抖的效果非常差、一次按键被误读多次,严重影响使用体验

消抖:
打开gpio.c文件

/* USER CODE BEGIN 0 */
#define KEY1  HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)//读取按键1
#define KEY2  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)//读取按键2  
#define KEY3  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_2)//读取按键3
#define KEY4  HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_3)//读取按键4

#define KEY1_PRES   1	//KEY1按下
#define KEY2_PRES	2	//KEY2按下
#define KEY3_PRES	3	//KEY3按下
#define KEY4_PRES	4 //KEY4按下
/* USER CODE END 0 */

本篇作为例程我只用了1个按键,一般来说用到了按键,肯定不会只用1个,这里的代码我按照4个按键来写的

接着再写入检测按键函数

/* USER CODE BEGIN 2 */
//按键处理函数
//返回按键值
//0 没有键按下
//1 KEY1按下
//2 KEY2按下
//3 KEY3按下
//4 KEY4按下
//优先响应级别:KEY0>KEY1>KEY2>KEY3
uint8_t KEY_Scan(uint8_t mode)
{	 
	static uint8_t key_up=1;//按键松开标志位
	if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
	{
		HAL_Delay(10);//去抖动
		key_up=0;
		if(KEY1==0)return KEY1_PRES;
		else if(KEY2==0)return KEY2_PRES;
		else if(KEY3==0)return KEY3_PRES;
		else if(KEY4==0)return KEY4_PRES;
	}
	else if(KEY1==1||KEY2==1||KEY3==1||KEY4==1)key_up=1; 	    
 	return 0;//无按键按下
}
/* USER CODE END 2 */

接着回到main.c文件

/* USER CODE BEGIN Includes */
#define KEY1_PRES   1	//KEY1按下
#define KEY2_PRES	2	//KEY2按下
#define KEY3_PRES	3	//KEY3按下
#define KEY4_PRES	4   //KEY4按下
/* USER CODE END Includes */

在while里写入

/* USER CODE BEGIN 3 */			   
	switch(KEY_Scan(0))
	{				 
		case KEY1_PRES:	
			HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
			break;
		case KEY2_PRES:	
			
			break;
		case KEY3_PRES:	
			
		  break;
        case KEY4_PRES:
			
			break;
	}
	/*if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin) == 0)
	{
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
	}*/
  }
  /* USER CODE END 3 */

编译下载时需要选择相对应的下载器,勾选以下

esp32按键开关_按键消抖_09


消抖效果如图