STM32——GPIO输入——按键检测

2023-10-29

硬件介绍

在这里插入图片描述
当按键置空时,IO接地
按键按下之后,IO口接通3.3V高电压,电流比较大,为了避免损坏IO,这里需要加装一个限流电阻。可以看到IO口是默认低电平,按键按下后产生一个上升沿,和平常的电路设计不太一样。这是因为PA0还具有一种自动唤醒的功能叫Weakup,Weakup必须要是上升沿才能唤醒的。
电容C6以及C14是用来做硬件消抖的。其原理就是,机械按键在按下的过程大约有20ms,在这个过程中,IO与3.3V电源不断地接通,相当于形成了一个交流电,这时有电容的话,这个过程就相当于是在给这个电容不断地充放电,当按键稳定之后,电容里的电荷又会通过接地线释放。

原理介绍

我们的STM32单片机,GPIO输出可以是ODR,BSRR,BRR寄存器来控制,其输入则是通过ODR寄存器来控制实现。
在这里插入图片描述
ODR寄存器也是低16位有效,如果对应的位读出来是0,表示检测到的是低电平,如果是1则是检测到高电平3.3V,即按键被按下。
这里的按键检测主要采用查询的方式,后续大家会学习到中断的按键检测。

实际代码操作

bsp_key.h

本节的工程代码,直接在之前固件库点亮LED的基础上继续加工。
首先我们在原有工程的基础上,在USER文件夹中新建一个key文件夹,用来放我们的驱动函数以及头文件bsp_key.c和bsp_key.h。
打开工程,将上面的C文件添加到我们的工程,同时在仙女棒里指定一下头文件的路径。然后再bsp_key.c中将我们的.h文件包含进来。

在驱动函数中,我们首先对GPIO进行一个初始化,这个过程跟之前初始LED的GPIO是类似的,需要修改的地方就是Pin,Mode以及RCC。

/***********************bsp_key.h******************/
//1.避免重复调用头文件报错
#ifndef _KEY_H
#define _KEY_H

//2.调用总头文件
#include "stm32f10x.h"

//3.对硬件部分的宏定义
#define KEY1_GPIO_PIN			GPIO_Pin_0
#define KEY1_GPIO_PART			GPIOA
#define KEY1_GPIO_CLK			RCC_APB2Periph_GPIOA

#define KEY2_GPIO_PIN			GPIO_Pin_13
#define KEY2_GPIO_PART			GPIOC
#define KEY2_GPIO_CLK			RCC_APB2Periph_GPIOC

//4.串口初始化函数以及串口状态扫描函数
void KEY_GPIO_Config(void);
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);

//5.按键按下标志宏
/**	若按键按下为高电平,设置KEY_ON = 1,KEY_OFF = 0
*	若按键按下为低电平,设置KEY_ON = 0,KEY_OFF = 1
*/
#define KEY_ON		1
#define KEY_OFF		0

#endif /*_KEY_H*/

驱动函数bsp_key.c

1.初始化操作
这部分和之前点亮LED灯是一样的。

/*********************bsp_key.c**********************/
//按键端口初始化函数
void KEY_GPIO_Config()
{
	//首先定义一个结构体类型
	GPIO_InitTypeDef GPIO_InitStruct;
	//时钟使能
	RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK, ENABLE);
	//选择按键的引脚进行配置
	GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(KEY1_GPIO_PART, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(KEY2_GPIO_PART, &GPIO_InitStruct);
	
}

2.按键检测
我们写一个函数void Key_Scan(),根据我们的需求可以知道,他可以传入两个形参,端口以及具体的引脚号,通过KEY_Scan()就可以扫描按键的状态。
GPIO引脚的输入电平可通过读取IDR寄存器对应的数据位来感知,而STM32标准库中就有相关函数,我们可以在stm32f10x_gpio.h的末尾所有函数的声明中找到我们需要的这个函数GPIO_ReadInputDataBit(),然后右键点击查看他的具体函数结构。该函数输入GPIO端口及引脚号,返回该引脚的电平状态,高电平返回1,低电平返回0 。
那么这里就可以设计我们的KEY_Scan()了:
a、首先我们已经明确了函数的功能是检测是否有按键按下,那么这就是一个具有返回值的函数,对于具有返回值的函数,我们就不用void来声明了,相对应的我们根据其返回值类型对其进行声明,同时我们也知道他的两个输入参数是端口和引脚。
这一部分的C语言知识,大家可以看这个教程连接:C函数教程

uint8_t KEY_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{

}

b、然后就是函数的具体内容,首先我们为了检测按键是否被按下,我们要将GPIO_ReadInputDataBit()函数读取到的结果与我们定义好的宏KEY_ON进行比较,那么如果检测到了按键被按下,我们就直接返回KEY_ON是否可以呢?答案当然是不行的,因为我们在一次按键操作的过程中,按键被按下是程序会一直扫描他的状态,每一次扫描程序都会认为我们完成了一次按键操作,这就相当于我们其实只按了一次,但是单片机认为我们按了无数次。
为了避免这个问题,我们使用while循环持续监测案件状态,直到按键被释放,我们才返回一个KEY_ON的值,如果没有按键按下,那么就直接返回KEY_OFF。

/**
	*@brief	检测是否有按键按下
	*@param GPIOx:具体的端口,x可以是(A_G)
	*@param GPIO_PIN:具体的端口位,可以是GPIO_Pin_x(0-15)
	*@retval 按键的状态
	*	@arg KEY_ON:按键按下
	*	@arg KEY_OFF:按键没按下
	*/
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
	if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
	{
		while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
		return KEY_ON;
	}else
		return KEY_OFF;
}

c、消除抖动:因为之前的讲解中已经说过,本电路因为有硬件消抖,所以不需要做消抖处理,如果硬件没有设计这部分的内容,那么就需要我们自己在KEY_Scan()这个函数中做软件滤波,防止波纹抖动引起的误触发。

到这里bsp_key.c文件中的内容也就完成了。下一步就是mian函数了。

int mian()
{
		/*端口初始化*/
	LED_GPIO_Config();
	KEY_GPIO_Config();
	
	/*查询按键状态,若按键按下,开启或关闭LED*/
	while(1)
	{
		if(KEY_Scan(KEY1_GPIO_PART,KEY1_GPIO_PIN)==KEY_ON){
			GPIO_SetBits(LED_G_GPIO_PART,LED_G_GPIO_PIN);
		}
		if(KEY_Scan(KEY2_GPIO_PART,KEY2_GPIO_PIN)==KEY_ON){
			GPIO_ResetBits(LED_G_GPIO_PART,LED_G_GPIO_PIN);
		}
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32——GPIO输入——按键检测 的相关文章

随机推荐

  • python3导入urllib2_两种兼容Python2和Python3的导入库的方法

    Python3和Python2是不兼容的 但是由于一些历史遗留问题 比如一些服务器只安装有Python2 一些安装有Python3 所以我们在实际写代码的时候就不得不考虑兼容Python2和Python3了 下面简单介绍两种兼容Python
  • Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]

    Android取经之路 的源码都基于Android Q 10 0 进行分析 Android取经之路 系列文章 系统启动篇 Android系统架构Android是怎么启动的Android 10 0系统启动之init进程Android10 0系
  • Python:小球反弹

    问题描述 已知一球从高空落下时 每次落地后反弹至原高度的四分之一再落下 编写一程序 从键盘输入整数n和m 求该球从n米的高空落下后 第m次落地时共经过的路程以及第m次落地后反弹的高度 并输出结果 输入形式 从键盘输入整数n和m 输出形式 输
  • 毕业设计 基于python的网络爬虫-基于python的网络爬虫

    一 从小说网站抓取一本小说 import urllib2 python库 提供一系列针对url的操作方法 import re re正则表达式 提供了一系列针对正则表达式的方法 BeautifulSoup4库 from bs4 import
  • Android 日志分析01-命令篇

    我回来了 很久没更新博客了 各种原因吧 但现在我决定回归博客 继续写写文章 分享分享技术 用过很多语言 涉及前后端 一时也不知从何讲起 往后慢慢梳理吧 慢慢把自己想分享的东西写下来 也是一种整理和记录吧 今天先分享Android知识 分享一
  • automake创建Makefile

    autoconf automake主要用于创建makefile 本文主要介绍一下automake的简单用法 Ubuntu下安装automake sudo apt get install automake 即可安装automake的相关工具
  • win10安装Mathtype报错处理,找不到MPlugin.dll

    在Mathtype官方中文网下载mathtype后 双击exe文件进行安装 不使用默认安装路径 安装后会弹出如下错误 由于找不到MPlugin dll 无法继续执行代码 重新安装程序可能会解决此问题 查看mathtype的安装目录 可以发现
  • CSDN社区之星专访:我的蜕变之路

    摘要 社区之星第49期采访了爱奇艺研发总监陆其明 他分享了个人生涯 管理和程序员素养等方面的看法 管理上他认为对人要领导 要管的是事 而在程序员素养上 他则引用Jeff Atwood的话称 成为优秀程序员的方法就是抛开编程 原文链接 htt
  • SRNet:Deep Residual Network for Steganalysis of Digital Images

    Abstract 现有的网络架构包括手工设计元素 比如固定域或限制卷积核 关键 有效扩展检测器前端 计算噪声残差 池化会不可避免地压制隐写噪声 在频域中有一个较好的结果 相对空域 更进一步提升是将选择通道作为第二通道 I 介绍 1 隐写术介
  • Ubuntu16.04桌面突然卡住怎么办?

    不知道有没有小伙伴和我一样 正在Ubuntu上工作呢 突然桌面就卡住了 键盘也没了反应 鼠标那个箭头只能移动 但是点击时却没有反应 作为一个Ubuntu小白 在最近的学习过程中遇到了好多问题 我把这些问题需要注意的地方记录下来 希望可以帮助
  • JMC性能监测

    文章目录 一 打开JMC 二 界面说明 三 配置java监测 四 总结 性能监测图形化 通过jdk自带的JMC工具即可轻松实现 JMC的全称为java mission control 意思为java程序任务控制台 一 打开JMC 在你下载好
  • 图解通信原理与案例分析-9:SFP光通信案例--数字信号的2-ASK光调制解调

    文本以SFP光模块的内部实现为案例 介绍数字电信号的光信号调制解调的基本原理 即如何把二进制的数字电信号调制到光信号上进行传输 反之 如何从光信号中解调出二进制的数字电信号 这部分的调制解调 完全是有SFP硬件实现的 不需要软件的编码 1
  • 关于Qt关闭程序但保持程序后台运行的坑(非常棘手)

    1 先说说我的后台程序的应用场景 关闭当前程序 隐藏 调用另一个ui ui的类型是悬浮窗 Qt Tool 并且在系统通知栏可以见到图标 后台程序逻辑都正常执行 2 实现后台运行的两种主要方式 1 重写closeEvent 并设置event
  • javaswing 设置背景图片

    背景图片的路径用自己的 改一下 package com gao import java awt import java awt event ActionEvent import java awt event ActionListener i
  • 树莓派不能上网解决方案

    判断自己的树莓派能不能上网 用这条命令试试 ping www baidu com ping www baidu com Temporary failure in name resolution 出现了以上错误 说明树莓派不能上网 解决思路
  • css3实现hover颜色,背景色,宽度等平滑变动(transition)

  • webpack 和html-webpack-plugin版本对应问题

    为了实现功能 配置生成预览页面 以前是 要实现的效果是 直接打开设置的首页 这里由于版本对应问题 一直报错 当前版本 devDependencies html webpack plugin 2 30 1 webpack 3 6 0 webp
  • idea使用lombok插件不能生效的原因

    要成功的使用lombok插件 需要3个步骤 一 需要先在idea中下载Lombok plugin 点击File gt settings gt plugins gt 然后点击以下图中所示 接着 在输入框输入lombok进行搜索 之后点击安装便
  • 粤嵌GEC6818-学习笔记2-屏幕相关及音频播放

    这里写目录标题 LCD屏幕 简介 操作 打开屏幕 映射 如何让plcd指向屏幕首地址 BMP图片的解析 把一张BMP格式的图片显示在我们的开发板上 触摸板的相关操作 练习 获取屏幕坐标 线程进程 练习 创建广告播放的一个线程 音频播放 播放
  • STM32——GPIO输入——按键检测

    硬件介绍 当按键置空时 IO接地 按键按下之后 IO口接通3 3V高电压 电流比较大 为了避免损坏IO 这里需要加装一个限流电阻 可以看到IO口是默认低电平 按键按下后产生一个上升沿 和平常的电路设计不太一样 这是因为PA0还具有一种自动唤