STM32CubeIDE基础学习-KEY按键输入实验

STM32CubeIDE基础学习-KEY按键输入实验



前言

前面学习了GPIO作为输出功能的实验,现在来学习GPIO作为输入功能的实验,直接在BEEP的工程基础上进行添加KEY的功能代码就行,其它的功能不用修改。

STM32CubeIDE基础知识学习回顾

实验目的:
学习配置GPIO作为输入功能使用,从而实现按键控制BEEP和LED状态翻转功能。


第1章 硬件介绍

本实验使用的开发板主控芯片是STM32F103C8T6,其核心原理图如下:

在这里插入图片描述

时钟来源使用的是外部高速8M晶振作为高速时钟。

KEY_UP按键接到芯片的PA0引脚上,KEY按键接到芯片的PA2引脚上,原理图如下图所示:

在这里插入图片描述

使用时需要注意它们的连接方式,它们两者是有区别的,代码配置是也会不一样,KEY_UP采用下拉输入模式,KEY采用上拉输入模式。

第2章 工程配置

本实验直接采用上一个蜂鸣器实验的工程作为基础模板,直接拷贝粘贴即可,然后在上面添加KEY的相关功能配置即可,其它不用修改,就不用再新建工程了。

2.1 工程外设配置部分

配置GPIO,如果找不到芯片引脚,可以在右下角进行搜索,就可以看到芯片对应的引脚出现黑色闪烁的,然后点击进行选择需要配置的功能即可。

鼠标左键点击该引脚,选择对应需要的功能,按键输入实验的使用选择配置为输入功能就行。如下图所示:

在这里插入图片描述

端口功能配置如下:
1、模式配置为输入模式。
2、更据硬件原理图来设置输出上拉/下拉。
3、User Label建议定义一个自己喜欢见名知意的名字,方便写程序时查看和方便使用。

具体的引脚配置如下图所示:

在这里插入图片描述

注意:为了确保能稳定正确读取到按键的触发电平,这里KEY_UP是需要配置下拉输入。

在这里插入图片描述

注意:为了确保能稳定正确读取到按键的触发电平,这里KEY是需要配置上拉输入。

RCC时钟、调试接口都不用修改,保持默认配置即可。

添加的引脚如下图所示

在这里插入图片描述

到此,整个工程需要新增的功能就配置完成了,接下来就可以生成代码工程进行代码编写了。

2.2 生成工程代码部分

可以按快捷键ALT+K,或者点击生成图标按钮生成代码工程。

生成后最终会显示下图这样的代码:

在这里插入图片描述

继承了前面的外设功能代码,接着就可以在上面添加自己需要实现的按键输入控制功能代码了。

第3章 代码编写

进入代码工程后,可以先点击编译一下代码,看代码工程是否会报错,如果没有警告和报错就可以进行代码编写了。不然如果在一开始的工程都报错了,后面就不好找问题了。

在main.h里面可以看到KEY相关的宏定义,如下图所示:

在这里插入图片描述
main函数里面的while循环里面可以写如下代码:

在这里插入图片描述

代码片示例如下:

if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)/* KEY_UP按下 */
{
	HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);
}

else if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)/* KEY按下 */
{
	 HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}

代码这样写完后下载到开发板后运行,按下按键后,可以发现是可以控制蜂鸣器和LED灯,但是并不是很稳定,而且还会有概率控制不了的现象,能成功的是偶然概率。

经过结合按键的工作原理分析,这样写按键代码是不严谨的,这就是导致功能异常的原因。

这种轻触按键按下时是会有抖动的,那么就需要做适当的处理才行,可以通过硬件或者软件的方式进行消除该问题。为了节约成本,一般都会采取软件的方式进行处理。常用的就是延时消抖,一般给10-20毫秒的延时基本可以解决按键按下时的抖动问题了,避免再次出现毛刺现象。

通过测试,当在按键按下后加了延时效果确实好了很多,如下图所示:

在这里插入图片描述

经过分析,虽然误触发的情况确实好了很多,但是发现按键按下不松手时,LED或蜂鸣器就会一直在触发翻转,为了让按键每按下一次,放开才触发一次,那么就需要给按键添加一个松手检测的处理操作,就在while里面一直死等判断,等按键状态发生改变时则退出循环,说明按键被松开了。如下图所示:

在这里插入图片描述

代码片示例如下:

if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)        /* KEY_UP按下 */
{
	HAL_Delay(20);      /* 延时消抖 */
	HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);
	while(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET);/* 松手检测 */
}

else if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)       /* KEY按下 */
{
  	HAL_Delay(20);      /* 延时消抖 */
	HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  	while(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET);   /* 松手检测 */
}

else
{
	HAL_Delay(20);       /* 延时消抖 */
}

添加完延时消抖和松手检测代码后,发现代码功能能达到预期效果了,说明这样写代码的逻辑是没问题的。

为了达到更佳的效果,可以适当添加按键按下确认判断语句,如下图所示:

在这里插入图片描述

代码片示例如下:

if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)        /* KEY_UP按下 */
{
	HAL_Delay(20);      /* 延时消抖 */
  	if(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET)    /* 确认KEY_UP按下 */
  	{
		HAL_GPIO_TogglePin(BEEP_GPIO_Port, BEEP_Pin);
  	}
  	while(HAL_GPIO_ReadPin(KEY_UP_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_SET);/* 松手检测 */
}

else if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)       /* KEY按下 */
{
  	HAL_Delay(20);      /* 延时消抖 */
  	if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_UP_Pin) == GPIO_PIN_RESET)     /* 确认KEY按下 */
  	{
	 	HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  	}
  	while(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET);    /* 松手检测 */
}

else
{
	HAL_Delay(20);       /* 延时消抖 */
}

到此,按键控制蜂鸣器和LED灯的代码就全部编写完成了。

附加部分
这样写出来的代码看上去代码量很多,很繁杂,可不可以再优化一下呢,当然可以的,可以再通过宏定义的方式进一步优化一下,让代码看起来更简略一些。

创建KEY文件夹,再创建key.h文件,在里面添加宏定义的代码如下图所示:

在这里插入图片描述

main文件里面的代码替换后如下图所示:

在这里插入图片描述

代码片示例如下:

while (1)
{
  	if(KEY_UP == GPIO_PIN_SET)
  	{
	  	HAL_Delay(20);              /* 延时消抖 */
	  	if(KEY_UP == GPIO_PIN_SET)   /* 确认按下 */
	  	{
		 	HAL_GPIO_TogglePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN);
	  	}
	  	while(KEY_UP == GPIO_PIN_SET);/* 松手检测 */
  	}

  	else if(KEY == GPIO_PIN_RESET)
  	{
	  	HAL_Delay(20);               /* 延时消抖 */
	  	if(KEY == GPIO_PIN_RESET)    /* 确认按下 */
	  	{
		 	 HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PIN);
	  	}
	 	 while(KEY == GPIO_PIN_RESET);/* 松手检测 */
  	}
  	
	else
	{
		HAL_Delay(20);       /* 延时消抖 */
	}
}

如果还要简短的,连BEEP翻转和LED翻转函数都可以进行宏定义,会更精简。

可以看到代码是短了许多,但还要注意main文件里面对应添加引入头文件路径才行,不然会报警告的。如下图所示:

在这里插入图片描述
添加完上面这些代码后,编译下载,就可以通过按键控制蜂鸣器和LED了。

第4章 实验现象

下载运行代码后,按一下WK_UP按键,可以让蜂鸣器的状态翻转,当长按不松手时,蜂鸣器会一直保持该状态,等松手再次按下后才会改变状态。同理,KEY按键也一样的现象。


总结

本实验实验使用的轻触按键是有抖动的,这种是按键本身的特性限制,无法避免,会有几毫秒的抖动毛刺,所以就需要通过延时来软件消除,通常给10ms差不多够了。如果不需要用软件的方式处理,那么可以增加硬件电路消除,就是在按键处并联一个电容也行。

按键判断逻辑:
if(按键按下)
{
  延时消抖
  if(再次确认是否按下)
  {
    执行控制代码
  }
  while(松手检测)
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-19 14:28:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-19 14:28:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-19 14:28:01       87 阅读
  4. Python语言-面向对象

    2024-03-19 14:28:01       96 阅读

热门阅读

  1. 解释MVC和MVVM架构模式

    2024-03-19 14:28:01       40 阅读
  2. 月度工作计划

    2024-03-19 14:28:01       35 阅读
  3. JupyterLab 暗色主题

    2024-03-19 14:28:01       36 阅读
  4. 在linux上发起get和post请,怎么写

    2024-03-19 14:28:01       32 阅读
  5. 微服务原理和实践

    2024-03-19 14:28:01       41 阅读
  6. 【已解决】c++ qt如何动态隐藏tabwidget中tab页

    2024-03-19 14:28:01       38 阅读
  7. Qt散文一

    2024-03-19 14:28:01       40 阅读
  8. 【Linux】cat & vim 命令存在着什么区别?

    2024-03-19 14:28:01       38 阅读
  9. LC 热题 100:数组与矩阵的探索之旅

    2024-03-19 14:28:01       35 阅读
  10. PostgreSQL和MySQL的异同

    2024-03-19 14:28:01       43 阅读