2.STM32CubeMX学习笔记二:STM32的按键开发基础

1. 按键信号是如何识别的?
一般来说,按键的两个引脚的一端通过电阻上拉到高电平,另一端则接地。
在没有按键按下的时候,输入引脚为高电平,当有按键按下,输入引脚则为低电平。通过反复读取按键输入引脚的信号,然后识别高低电平来判断是否有按键触发。

2. 为什么去抖动?
按键的输入引脚有低电平产生不代表一定是有按键按下,也许是干扰信号 , 因此,需要通过去抖动处理,将这些干扰信号过滤,从而获得真实的按键触发信号。

3. 如何去抖动
首次检测到按键输入引脚有低电平后,稍作延时,再次读取该引脚,如还是低电平,则确认为按键触发信号;否则,判断为干扰信号,不予处理。

GPIO_PinState  HAL_GPIO_ReadPin( GPIO_TypeDef* GPIOx,  uint16_t GPIO_Pin);

参数1:GPIOx,端口号,如:GPIOB,GPIOF。
参数2:GPIO_Pin,引脚号,如:GPIO_PIN_9,GPIO_PIN_12。
返回值:GPIO_PinState,引脚的电平状态。
应用举例:判断PE3引脚的输入信号,若为低电平,则将PB5引脚控制的LED灯的开关状态切换。    
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)  
{              
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);      
}

第一部分:根据开发板原理图,配置STM32CubeMX
1.开发板LED灯部分原理图如图所示:
LED原理图
由原理图不难看出,LED0的阴极与PB5引脚直接相连,LED1的阴极与PE5引脚直接相连,控制时,引脚为低电平,对应LED灯发光;引脚为高电平。对应LED灯熄灭。

2.开发板按键部分原理图如图所示:
按键原理图
从原理图中可以看出,两个用户自定义按键KEY0和KEY1中,分别与PE4和PE3引脚相连,此处画的不是很完整,完整的图应该如下图所示,是带上拉电阻的:
带上拉电阻的按键原理图
以KEY0为例,从带上拉电阻的按键示意图中可以看出,如果按键没有按下的话,上拉电阻左侧与地是不通的,那么PE4就会为高电平,如左下图所示;如果按键按下后,上拉电阻左侧与地直接连接,PE4和地等电位,为低电平。

上拉电阻按键控制引脚电平的示意图
关于上拉电阻,我的理解是这样的:电源到器件引脚上的电阻叫上拉电阻,作用是平时使该引脚为高电平,地到器件引脚上的电阻叫下拉电阻,作用是平时使该引脚为低电平。
也就是说,上下拉的目的都是给IO口设置一个默认的状态,上下拉电阻也不能够随意取消,这里以上拉电阻为例,起作用是给IO口默认高电平的状态。如果没有上拉电阻,电源直接接在IO口上,按键没有按下的时候,是高电平没有问题,如果按键按下了,就会造成电源和地直接相连的情况。
是否能缺少上拉电阻是一个图
至于为什么按键没有按下的时候,IO口默认为高电平,在这里我是这么理解的:IO口的高低电平,是相对于地来说的,我们看电源到地的回路,如果按键没有按下,相当于IO口和地之间的阻抗很大,这样的话按键没有按下PE4口是为高电平的,如果阻抗接近无穷的话,PE4对地电压是为5V。

3.配置STM32CubeMX
过程和之前大致相同,详见1.STM32的GPIO开发基础中的相同部分。
需要注意的是,在这里和按键相连的引脚,需要使用Input模式和上拉电阻状态。
引脚配置
第二部分:Keil5中代码的编写

按键扫描的过程中,需要进行去抖动操作,也就是当按键按下后,过一段时间再去判定,按键是不是真的按下了。在这里需要延时函数,如果不是特别精确的延时,用while循环即可:

void Delay(unsigned int t)  //延时函数
{
	while(t--);
}

扫描按键的时候,大体流程,就是判断与按键相连的IO口是否为指定电平:如果IO口为低电平,即为按键按下

void Scan_Keys()
{
	if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键对应IO口是否为低电平,即按键是否按下
	{
		Delay(1000);//延时函数,去抖动操作
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键是否真的按下了
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
			while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET);//如果按键对应IO口,为低电平,即按键按下一直未抬起,则一直执行循环,等按键抬起后,跳出循环
		}
		

这样写代码会比较麻烦,每一个按键都需要写对应引脚,很麻烦,为了避免这种情况,可以在代码前面进行宏定义,也可以在配置STM32CubeMx的时候直接添加User Label标签来解决问题:

/* USER CODE BEGIN PD */
#define KEY1 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)
#define KEY0 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)
/* USER CODE END PD */

低电平也可以直接用0来简化,这个是在gpio的文件中有说明的,可以直接使用,简化后的扫描按键代码如图所示:

/* USER CODE BEGIN 0 */
void Delay(unsigned int t)  //延时函数
{
	while(t--);
}

void Scan_Keys()
{		
	if(KEY1==0)
	{
		Delay(1000);
		if(KEY1==0)     //与if(KEY1==0)等价
			{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
			while(KEY1==0);
			}
	}
	if(KEY0==0)
		{
		Delay(1000);
		if(KEY0==0)     //与if(KEY0==0)等价
			{
			while(KEY0==0);//按下按键时,KEY0为低电平,一直执行while(1)循环,松开后再执行后续操作
			HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
			while(KEY0==0);
			}
		}
}
/* USER CODE END 0 */

main函数直接调用扫描按键函数即可:

 /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  	Scan_Keys();
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }

在这里也可以体会到,按下按键切换状态,与按下按键,松开之后再切换状态的区别,KEY1是按下即翻转电平,前面详细描述过;KEY0则是在判断按键真正按下去之后,再判断一下按键是否抬起,抬起后再执行后续操作。
写完代码后,在Keil5里编译好后,就可以下载到单片机中。

配套源码:利用STM32F103ZET6开发板基于HAL库的STM32学习笔记二:按键开发基础例程

参考内容:

上拉、下拉电阻的原理和作用
通俗易懂讲解上拉电阻和下拉电阻的原理

以上内容为本人学习b站小蜜蜂老师基于STM32CubeMX的嵌入式开发基础教程所做的笔记,其中有一些为个人的理解与感悟,如有疏漏之处,敬请大佬指正。

版权声明:本文为CSDN博主「砍省小苏苏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46301543/article/details/122453600

1. 按键信号是如何识别的?
一般来说,按键的两个引脚的一端通过电阻上拉到高电平,另一端则接地。
在没有按键按下的时候,输入引脚为高电平,当有按键按下,输入引脚则为低电平。通过反复读取按键输入引脚的信号,然后识别高低电平来判断是否有按键触发。

2. 为什么去抖动?
按键的输入引脚有低电平产生不代表一定是有按键按下,也许是干扰信号 , 因此,需要通过去抖动处理,将这些干扰信号过滤,从而获得真实的按键触发信号。

3. 如何去抖动
首次检测到按键输入引脚有低电平后,稍作延时,再次读取该引脚,如还是低电平,则确认为按键触发信号;否则,判断为干扰信号,不予处理。

GPIO_PinState  HAL_GPIO_ReadPin( GPIO_TypeDef* GPIOx,  uint16_t GPIO_Pin);

参数1:GPIOx,端口号,如:GPIOB,GPIOF。
参数2:GPIO_Pin,引脚号,如:GPIO_PIN_9,GPIO_PIN_12。
返回值:GPIO_PinState,引脚的电平状态。
应用举例:判断PE3引脚的输入信号,若为低电平,则将PB5引脚控制的LED灯的开关状态切换。    
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)  
{              
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);      
}

第一部分:根据开发板原理图,配置STM32CubeMX
1.开发板LED灯部分原理图如图所示:
LED原理图
由原理图不难看出,LED0的阴极与PB5引脚直接相连,LED1的阴极与PE5引脚直接相连,控制时,引脚为低电平,对应LED灯发光;引脚为高电平。对应LED灯熄灭。

2.开发板按键部分原理图如图所示:
按键原理图
从原理图中可以看出,两个用户自定义按键KEY0和KEY1中,分别与PE4和PE3引脚相连,此处画的不是很完整,完整的图应该如下图所示,是带上拉电阻的:
带上拉电阻的按键原理图
以KEY0为例,从带上拉电阻的按键示意图中可以看出,如果按键没有按下的话,上拉电阻左侧与地是不通的,那么PE4就会为高电平,如左下图所示;如果按键按下后,上拉电阻左侧与地直接连接,PE4和地等电位,为低电平。

上拉电阻按键控制引脚电平的示意图
关于上拉电阻,我的理解是这样的:电源到器件引脚上的电阻叫上拉电阻,作用是平时使该引脚为高电平,地到器件引脚上的电阻叫下拉电阻,作用是平时使该引脚为低电平。
也就是说,上下拉的目的都是给IO口设置一个默认的状态,上下拉电阻也不能够随意取消,这里以上拉电阻为例,起作用是给IO口默认高电平的状态。如果没有上拉电阻,电源直接接在IO口上,按键没有按下的时候,是高电平没有问题,如果按键按下了,就会造成电源和地直接相连的情况。
是否能缺少上拉电阻是一个图
至于为什么按键没有按下的时候,IO口默认为高电平,在这里我是这么理解的:IO口的高低电平,是相对于地来说的,我们看电源到地的回路,如果按键没有按下,相当于IO口和地之间的阻抗很大,这样的话按键没有按下PE4口是为高电平的,如果阻抗接近无穷的话,PE4对地电压是为5V。

3.配置STM32CubeMX
过程和之前大致相同,详见1.STM32的GPIO开发基础中的相同部分。
需要注意的是,在这里和按键相连的引脚,需要使用Input模式和上拉电阻状态。
引脚配置
第二部分:Keil5中代码的编写

按键扫描的过程中,需要进行去抖动操作,也就是当按键按下后,过一段时间再去判定,按键是不是真的按下了。在这里需要延时函数,如果不是特别精确的延时,用while循环即可:

void Delay(unsigned int t)  //延时函数
{
	while(t--);
}

扫描按键的时候,大体流程,就是判断与按键相连的IO口是否为指定电平:如果IO口为低电平,即为按键按下

void Scan_Keys()
{
	if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键对应IO口是否为低电平,即按键是否按下
	{
		Delay(1000);//延时函数,去抖动操作
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键是否真的按下了
		{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
			while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET);//如果按键对应IO口,为低电平,即按键按下一直未抬起,则一直执行循环,等按键抬起后,跳出循环
		}
		

这样写代码会比较麻烦,每一个按键都需要写对应引脚,很麻烦,为了避免这种情况,可以在代码前面进行宏定义,也可以在配置STM32CubeMx的时候直接添加User Label标签来解决问题:

/* USER CODE BEGIN PD */
#define KEY1 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)
#define KEY0 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)
/* USER CODE END PD */

低电平也可以直接用0来简化,这个是在gpio的文件中有说明的,可以直接使用,简化后的扫描按键代码如图所示:

/* USER CODE BEGIN 0 */
void Delay(unsigned int t)  //延时函数
{
	while(t--);
}

void Scan_Keys()
{		
	if(KEY1==0)
	{
		Delay(1000);
		if(KEY1==0)     //与if(KEY1==0)等价
			{
			HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
			while(KEY1==0);
			}
	}
	if(KEY0==0)
		{
		Delay(1000);
		if(KEY0==0)     //与if(KEY0==0)等价
			{
			while(KEY0==0);//按下按键时,KEY0为低电平,一直执行while(1)循环,松开后再执行后续操作
			HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
			while(KEY0==0);
			}
		}
}
/* USER CODE END 0 */

main函数直接调用扫描按键函数即可:

 /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  	Scan_Keys();
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }

在这里也可以体会到,按下按键切换状态,与按下按键,松开之后再切换状态的区别,KEY1是按下即翻转电平,前面详细描述过;KEY0则是在判断按键真正按下去之后,再判断一下按键是否抬起,抬起后再执行后续操作。
写完代码后,在Keil5里编译好后,就可以下载到单片机中。

配套源码:利用STM32F103ZET6开发板基于HAL库的STM32学习笔记二:按键开发基础例程

参考内容:

上拉、下拉电阻的原理和作用
通俗易懂讲解上拉电阻和下拉电阻的原理

以上内容为本人学习b站小蜜蜂老师基于STM32CubeMX的嵌入式开发基础教程所做的笔记,其中有一些为个人的理解与感悟,如有疏漏之处,敬请大佬指正。

版权声明:本文为CSDN博主「砍省小苏苏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46301543/article/details/122453600

生成海报
点赞 0

砍省小苏苏

我还没有学会写个人说明!

暂无评论

相关推荐

STM32F2————配置时钟延迟不准的问题

STM32F2配置时钟问题 笔者在本科毕业设计使用STM32F207芯片,但是在配置时钟时出现了问题。 问题 我按照F1写代码的延时函数放在F2竟然不准了 换个办法 使用Systick时钟也是不准,原因是笔者代

2.STM32CubeMX学习笔记二:STM32的按键开发基础

1. 按键信号是如何识别的? 一般来说,按键的两个引脚的一端通过电阻上拉到高电平,另一端则接地。 在没有按键按下的时候,输入引脚为高电平,当有按键按下,输入引脚则为低电平。通

基于STM32的高精度频率计设计

前言 本文记录了博主完成的一个课设作品(学分为3.5分),题目需要利用ARM做出一个高精度频率计。具体要求如下: 1)实现对10M以内数字信号频率的高精度测量&#xff0c

HAL库控制PS2手柄

吐槽一下 最近买了个ps2手柄,结果买家发的例程全都是好几年前的库函数版本,尝试移植基本没啥可能。虽然PS2手柄已经被开发很久了,不过我看网上用hal库来写控制的很少,例程也都是用库函数