【STM32基础 CubeMX】按键的检测

news2024/11/25 11:36:20

文章目录

  • 前言
  • 一、按键原理图分析
  • 二、cubeMX配置key GPIO
  • 三、代码分析
    • 3.1 cubemx生成的代码
    • 3.2 1个库函数
  • 四、按键点灯示例代码
  • 总结


前言

在嵌入式系统开发中,按键检测是一个基础而重要的任务,特别是在使用STM32系列微控制器的项目中。按键通常被用于与用户进行交互、控制设备的各种功能,或者触发特定事件。本文将介绍有关STM32基础按键检测的关键概念和方法。
通过按键检测,您可以实现多种功能,例如控制LED灯、切换设备模式、输入密码、启动/停止操作等。了解如何正确地检测按键状态是确保系统稳定性和用户友好性的关键一步。
在本文中,我们将探讨以下关键方面:

1.硬件连接:了解如何将外部按钮或开关连接到STM32微控制器的GPIO引脚,以便能够读取它们的状态。
2.GPIO配置:如何通过STM32的HAL库或LL库来配置GPIO引脚,使其适用于按键检测。
3.按键状态检测:如何读取GPIO引脚的状态以检测按键的按下和释放。
4.去抖动处理:解决机械按键可能引发的抖动问题,以确保准确的按键检测。
5.检测方法:使用轮询法或中断法来实现按键检测,根据项目的需求选择合适的方法。

通过深入了解这些关键概念和技术,您将能够成功地集成按键检测功能到您的STM32嵌入式项目中,并实现所需的用户交互和控制功能。在下一步中,我们将详细讨论每个方面,以帮助您更好地理解和应用STM32基础按键检测。


一、按键原理图分析

在这里插入图片描述
这个端口可以说是这样的:他一直给高电平(这样理解更好一些),当按键按下就短路了,然后跑到GND下面,此时这个读取到的东西就会改变,通过这个改变我们就可以判断是否按下了按键

二、cubeMX配置key GPIO

1、对应原理图找到key所在gpio
在这里插入图片描述

2、找到对应的GPIO,选择Input
在这里插入图片描述

3、配置gpio,设置上下拉

在这里插入图片描述

上下拉是什么呢?怎么理解:

当涉及到按键(按钮)时,“pull-up” 和 “pull-down” 是两种电气连接方式,它们用于确定按键的默认状态(按下或未按下)以及如何在电路中连接按键。

Pull-Up(上拉电阻):

通俗解释:上拉电阻就像是给按钮一根绳子,将按钮默认拽向高电平的状态。这意味着按钮未按下时,它的引脚连接到了正电压(例如3.3V或5V),从而保持在高电平状态。当您按下按钮时,它会将引脚拉向地(低电平状态)。

应用:常见于需要默认状态是高电平的情况,当按下按钮时,引脚变为低电平,例如在电子开关或触摸屏中。

Pull-Down(下拉电阻):

通俗解释:下拉电阻就像是给按钮一根绳子,将按钮默认拽向低电平的状态。这意味着按钮未按下时,它的引脚连接到地,从而保持在低电平状态。当您按下按钮时,它会将引脚拉向正电压(高电平状态)。

应用:常见于需要默认状态是低电平的情况,当按下按钮时,引脚变为高电平,例如在数字逻辑电路或数字输入设备中。

总之,上拉电阻和下拉电阻是一种电气设计方式,用于确定按钮的默认电平状态并防止电平漂移。选择哪种方式取决于您的应用需求,以确保按键在不同情况下的稳定工作。如果您希望按下按钮时引脚变成高电平,使用上拉电阻;如果希望按下按钮时引脚变成低电平,使用下拉电阻。

那么在这边我就设置了一个上拉。

三、代码分析

3.1 cubemx生成的代码

GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

在这里插入图片描述

代码详解:
GPIO_InitStruct.Pin = GPIO_PIN_4;

这行代码设置了一个名为GPIO_InitStruct的结构体中的成员Pin。GPIO_PIN_4是一个宏定义,表示要初始化的GPIO引脚的编号。在这里,它表示要初始化的是GPIOE端口的第4个引脚。

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

这行代码设置了结构体中的成员Mode。GPIO_MODE_INPUT是一个宏定义,表示将该GPIO引脚配置为输入模式,即该引脚用于接收外部信号,而不是输出信号。

GPIO_InitStruct.Pull = GPIO_PULLUP;

这行代码设置了结构体中的成员Pull。GPIO_PULLUP是一个宏定义,表示启用了上拉电阻。这意味着当没有外部信号输入时,引脚将被默认拉向高电平(3.3V或5V,具体取决于芯片工作电压)。这有助于防止引脚漂移到未定义的电平。

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

最后,这行代码调用HAL库函数HAL_GPIO_Init来应用之前设置的配置信息。它告诉STM32芯片初始化GPIOE端口的第4个引脚,将其配置为输入模式,并启用上拉电阻。这样,该引脚就准备好接收外部信号,并且在没有信号输入时保持高电平状态。

这段代码常用于初始化一个GPIO引脚,以便将其用作输入引脚,并确保引脚的默认状态是高电平,以防止信号漂移。这在连接外部按钮或开关等输入设备时非常有用。

3.2 1个库函数

HAL_GPIO_ReadPin 函数的函数原型如下:

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

在这里插入图片描述

作用:
HAL_GPIO_ReadPin 用于读取指定GPIO引脚的电平状态,即判断该引脚当前是高电平还是低电平。这对于检测外部信号(例如按钮按下或释放)非常有用,以便根据引脚状态执行相应的操作。

参数:

GPIOx:这是一个指向GPIO端口(例如GPIOA、GPIOB、GPIOC等)的指针,指定要读取引脚状态的GPIO端口。
Pin:这是一个宏定义或者按位或操作组成的数值,表示要读取的GPIO引脚的编号。例如,要读取GPIOA端口的第5个引脚,可以使用GPIO_PIN_5。
返回值:
HAL_GPIO_ReadPin 函数的返回值是一个整数,表示指定GPIO引脚的电平状态。通常情况下:

如果引脚是高电平,返回值为非零(例如1)。
如果引脚是低电平,返回值为零。
这样,您可以根据返回值来判断引脚的状态,进而执行相应的逻辑。例如,您可以使用该函数检测按钮是否按下,如果返回值为非零,表示按钮被按下,如果返回值为零,表示按钮未被按下。

示例用法:

if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) != 0) 
{
    // 按钮被按下,执行相应操作
} 
else 
{
    // 按钮未被按下,执行其他操作
}

在这里插入图片描述

这样,HAL_GPIO_ReadPin 函数帮助您轻松读取GPIO引脚的状态,以便在嵌入式应用中做出决策。

四、按键点灯示例代码

我这里设置的是上拉电阻,按下后为低电平
示例代码如下:

while (1)
{
  /* USER CODE END WHILE */

	if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == 0)
	{
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == 0)
		{
			state = ! state;
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,state);
		}
	}

  /* USER CODE BEGIN 3 */
}

在这里插入图片描述

代码解释如下:
这段代码看起来是一个在嵌入式系统中的主循环,主要是在不断地检测一个GPIO引脚的状态,并且根据该状态执行一些操作。下面逐行解释这些代码:

1.while (1)
这是一个无限循环,表示程序会一直在这个循环中运行,直到外部因素导致程序退出或者重启。
2.if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == 0)
这行代码通过调用HAL_GPIO_ReadPin函数来检测GPIOE端口的第4个引脚(即GPIOPIN4)的状态是否为低电平(0)。如果条件成立,说明检测到了某种外部信号,通常是按钮按下的信号。
3.HAL_Delay(10);
在进一步检测按钮状态之前,这行代码引入了一个延时。延时的时间是10毫秒,即程序会等待10毫秒。这个延时的目的是为了稳定信号的检测。按钮在按下或释放的瞬间可能会产生电压噪声或者抖动,延时有助于消除这种抖动,确保稳定地检测按钮的状态。
4.if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) == 0)
在上面的延时之后,再次检测GPIOE端口的第4个引脚的状态是否为低电平。这是为了确认按钮状态稳定地为低电平,而不是短时的电压抖动。
5.state = !state;
如果按钮状态确认为低电平,那么会执行这行代码。它将一个变量state的值取反,即如果state是1,则变成0,如果state是0,则变成1。
6.HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, state);
这行代码根据前面的操作,将state的值写入GPIOB端口的第5个引脚。这实际上是在控制一个输出引脚,根据按钮的按下来切换输出状态(通常是驱动一个LED或执行其他操作)。

为什么需要延时再检测按钮状态?这是因为在按钮按下或释放的瞬间,按钮的引脚可能会发生电压抖动,导致信号从低电平切换到高电平或反之。通过引入延时,可以等待这种抖动稳定下来,以便在稳定的状态下进行检测,从而避免不必要的误触发或多次触发。这是一种常见的做法,特别是在处理物理输入设备(如按钮)时,以确保稳定的信号检测。这个就叫做按键去抖动


总结

在STM32嵌入式系统中,按键检测是常见的基础任务之一,通常用于检测外部按钮或开关的状态变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1053751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ - 开放地址法的哈希介绍 - 哈希表的仿函数例子

前言 哈希其实是一种搜索方式,像暴力查找,有序数组的二分查找,二分查找就很快了,可以达到O(log n)。但是有序数组有一个 弊端,就是要先进行排序,这就有消耗,这还好,当要插入删除修改…

Go-Python-Java-C-LeetCode高分解法-第八周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏,每日一题,和博主一起进步 LeetCode专栏 本文部分内容来自网上搜集与个人实践。如果任何信息存在错误,欢迎…

UE5.1编辑器拓展【一、脚本化资产行为,通知,弹窗,高效复制多个同样的资产】

目录​​​​​​​ 插件制作 添加新的类:AssetActionUtility 添加新的模块:EditorScriptingUtilities 路径了解 添加debug的头文件 代码【debug.h】内涵注释: 写函数 .h文件 .cpp文件 插件制作 首先第一步是做一个插件&#xff1a…

Flink中序列化RoaringBitmap不同方式的对比

背景 在flink中,我们有时候会使用到RoaringBitmap进行统计计数等操作,而当使用RoaringBitmap时,这就涉及到了最重要的问题,如何序列化?序列化的目的是为了进行网络通信或者状态序列化的目的,本文的重点是比…

根据GWAS数据估算样本量N和使用千人基因组填充maf的参考文献

https://github.com/GenomicSEM/GenomicSEM/wiki/2.1-Calculating-Sum-of-Effective-Sample-Size-and-Preparing-GWAS-Summary-Statistics

【LeetCode热题100】--104.二叉树的最大深度

104.二叉树的最大深度 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) …

尚硅谷谷粒商城部分报错问题处理

1、启动报错: 内容: org.springframework.beans.factory.BeanCreationException: Error creating bean with name attrAttrgroupRelationController: Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed t…

使用prometheus监控java服务

在prometheus官方下载页面没有看到jvm_exproter的下载地址但是官方页面是有推荐下载地址的 访问 Prometheus - Monitoring system & time series database prometheus官方网址 官方推荐地址下载是在github网络访问不方便的可以用下面的网址 wget https://repo1.maven…

【小程序 - 基础】页面导航、页面事件、生命周期、WXS脚本_04

目录 一、页面导航 1. 什么是页面导航 2. 小程序中实现页面导航的两种方式 2.1 声明式导航 2.1.1 导航到 tabBar 页面 2.1.2 导航到非 tabBar 页面 2.1.3 后退导航 2.2 编程式导航 2.2.1 导航到 tabBar 页面 2.2.2 导航到非 tabBar 页面 2.2.3 后退导航 2.3. 导航…

Proxyer实现内网穿透云服务器

Proxyer Proxyer是一个网络代理工具,它可以将本地计算机的网络流量(如HTTP、HTTPS、TCP等)转发到远程服务器。使用Proxyer可以在本地计算机上建立一个代理服务器,通过代理服务器来访问互联网上的资源。 yum仓库设置 rm -f /etc…

在Ubuntu上通过Portainer部署微服务项目

这篇文章主要记录自己在ubuntu上部署自己的微服务应用的过程,文章中使用了docker、docker-compose和portainer,在部署过程中遇到了不少问题,因为博主也是初学docker-compose,通过这次部署实战确实有所收获,在这篇文章一…

LeetCode【121. 买卖股票的最佳时机】

你才不是什么小人物,你在我这里,是所有的天气和心情。 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一…

idea Springboot 校园助学贷款系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 校园助学贷款系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统 具有完整的源代码和数据库&…

小谈设计模式(8)—代理模式

小谈设计模式(8)—代理模式 专栏介绍专栏地址专栏介绍 代理模式代理模式角色分析抽象主题(Subject)真实主题(Real Subject)代理(Proxy) 应用场景远程代理虚拟代理安全代理智能引用代…

ubuntu22.04 x11窗口环境手势控制

ubuntu22.04 x11窗口环境手势控制 ubuntu x11窗口环境的手势控制并不优秀,我们可以使用touchegg去代替 这个配置过程非常简单,并且可以很容易在一定范围内达到你想到的效果,类比mac的手势控制 关于安装 首先添加源,并安装 sud…

数据结构-----二叉排序树

目录 前言 1.什么是二叉排序树 2.如何构建二叉排序树 3.二叉排序树的操作 3.1定义节点储存方式 3.2插入节点操作 3.2创建二叉排序树 3.4遍历输出(中序遍历) 3.5数据查找操作 3.6获取最大值和最小值 3.7删除节点操作 3.8销毁二叉排序树 4.完…

漏斗分析模型

从业务流程起点开始到最后日标完成的每个环节都会有用户流失,因此需要一种分析方法来衡量业务流程每一步的转化效率,漏斗分析方法就是这样的分析方法。 例如,在淘宝上一款商品的浏览量是 300、点击量是 100、订单量是 20、支付量是 10&#…

centos 部署nginx 并配置https

centos版本:centos 7.8 (最好不要用8,8的很多用法和7相差很大) 一.安装nginx 1。下载Nginx安装包:首先,访问Nginx的官方网站(https://nginx.org/)或您选择的镜像站点,找…

Linux知识点+命令

1. 简介 Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。 Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议。它支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的…

BUUCTF reverse wp 81 - 85

[SCTF2019]babyre 反编译失败, 有花指令 有一个无用字节, 阻止反编译, patch成0x90 所有标红的地方nop掉之后按p重申函数main和loc_C22, F5成功 int __cdecl main(int argc, const char **argv, const char **envp) {char v4; // [rspFh] [rbp-151h]int v5; // [rsp10h] [rb…