详细了解stm32---按键

news/2024/11/7 18:13:19/

提示:永远支持知识文档免费开源,喜欢的朋友们,点个关注吧!蟹蟹!

目录

一、了解按键

二、stm32f103按键分析

三、按键应用


一、了解按键

         同学们,又见面了o(* ̄▽ ̄*)ブ,最近降温了,注意保暖哦!这次我们来了解stm32中的按键操作 ,首先我们需要了解什么是按键,以及按键的基本结构,如下图就是我们按键的基本结构:

按键是什么呢?说专业一点,按键就是一种电子开关使用时轻轻按开关按钮就可以使开关接通,当松开手的时候,开关断开。说白了按键就是用来实现一个电路的通路以及断开操作的开关。

看完上图之后我们该如何给按键接线呢?假设我们一定要接1引脚,但是接1,2呢?、还是接1,3呢?假设我们接的是1,3,此时电路是不是一直是通路,当我们按下按键和不按下按键是不是都是同一个结果,因为1,3相连引脚初始是导通的,那我们还能实现按键操作吗?不能吧,所以我们应该接1,2引脚吧,同样的我们也可以接1,4引脚对吧,等等。

通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号如图:

在图中我们可以看出,理想的按键电压信号波形图是空闲状态维持一种电平(低电平或者是高电平,具体需要我们自己根据电路图配置),当我们 按下按键的时候,电压信号波形产生一个跳变吧,当我们松开按键的时候电压又跳变回原来的状态,有了这种跳变,我们是不是就可以根据电压的这一特性来实现控制某一个灯的开关啦,或者某一外设的开关?

但实际情况却有些差强人意,因为当我们按下按键的时候,按键会产生一个机械抖动,这个抖动会影响我们对电压信号波形的判断,就比如我们不小心碰了一下按键,灯就开了,这样过于灵敏是不是不太好呀?那我们该如何去解决这个问题呢?可以用延时吧?就是那个systick,延时10ms或者20ms,当经过10ms之后如果电平还是维持在一个低电平或者高电平我们是不是就可以判断按键按下了,这样就可以解决误触这个问题了,当然这不是最优解决方法,更优解决方法我们可以通过外部中断去实现。

 ok,知道这些之后我们接下来可以通过按键来实现stm32上的一个灯的控制了,我们先来分析按键的原理图

二、stm32f103按键分析

我们怎么去看这个图呢?看网络标号吧,看网络标号对应哪个引脚吧,比如这个WK_UP这个网络标号就连接在如下图:

WK_UP对应的引脚是PA0吧,这个按键我们可以用来当作一个普通的按键来用,当然也可以用来当作唤醒,外部中断的一个唤醒按键,那什么时候需要唤醒呢?就是当我们的这个芯片进入到一个睡眠模式,或者是待机模式,或者什么什么模式,反正就是低功耗的模式里面其中一种,我们可以通过这个按键来唤醒我们这个系统。

我们先来分析一下,我们这个按键按下之后识别到什么电平:

我们拿WK_UP(PA0)引脚来举例,当我们按下按键之后,我们在引脚可以识别到一个高电平吧?为什么?因为我们这个按键外部接了一个3.3V的上拉电阻,当我们按下按键之后我们就可以读到一个高电平。再问大家一个问题,我们WK_UP(PA0)引脚该配置成输入还是输出模式呢?我们站在芯片的角度考虑,我们是需要去读取WK_UP(PA0)引脚的输出电平对吧,所以我们是需要将WK_UP(PA0)配置成输入模式。我们通过读取它的电平变化来判断按键是否按下。那么就需要WK_UP(PA0)引脚有一个电平的变化,这样我们才能通过这个电平的变化来判断按键是否按下。好,那么,当我们按键有按下的时候WK_UP(PA0)引脚处于高电平,而我们又需要这个引脚有一个电平跳变,故我们应该给这个引脚配置成下拉输入模式吧,这样,当WK_UP(PA0)引脚处于空闲状态时就处于低电平,当我们按下按键的时候电平跳变成高电平,所以我们就可以通过这个电平变化来判断按键是否按下。

三、按键应用

ok,我们现在可以来尝试着写一下代码,我们板子上有三个按键,我们尝试着用WK_UP(PA0)来点亮灯,用PC8来熄灭灯,用PC9来使灯闪烁。

代码如下:

首先我们要知道一个函数(以下的函数在固件库中可以查询到):

其中有两个 函数我们需要注意:

GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, u16 GPIO_Pin);

GPIO_ReadInputData(GPIO_TypeDef* GPIOx)

其中:

第一个函数有两个参数,第一个是选择要读取的GPIO,第二个参数是选择要读取的GPIO对应的引脚

第二个函数就只有一个参数,也就是说第二个函数使用来读取一组GPIO引脚的

我们用按键点灯需要的是一个引脚吧,不需要读取一组GPIO吧,所以我们选择第一个函数进行GPIO的输入读取。

好,知道这些之后我们就可以正式开始写代码了:

代码如下:

key.c文件:

#include "key.h"
u8 key_flag;
void Key_Init(void)
{GPIO_InitTypeDef  GPIO_InitStruct;/*打开时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);/*配置GPIO*/GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;/*下拉输入*/GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;/*上拉输入*/GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;GPIO_Init(GPIOC, &GPIO_InitStruct);
}void Read_Key(void)
{/***以下的代码还有很多可以修改的地方,比如说可以用位带操作简化GPIO读取操作,还可以用外部中断来处理延时产生的问题等等***/if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == SET){/*消除抖动*/delay_ms(20);if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == SET){key_flag = 1; }if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8) == RESET){key_flag =  2;}if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_9) == RESET){key_flag = 3;}}
}

main.c文件:

#include "systick.h"
#include "usart_drv.h"
#include "key.h"
#include "led.h"
extern u8 key_flag;
void HardWare_Init(void)
{SysTick_Init(72);Usart_MyConfig(115200);//这个串口可以用来调试代码用Key_Init();
}int main(void)
{HardWare_Init();while(1){Read_Key();switch (key_flag){case 1:LED_Ctrl(LED_0, LED_ON);break;case 2:LED_Ctrl(LED_0, LED_OFF);break;case 3:delay_ms(200);LED_Ctrl(LED_0, LED_ON);delay_ms(200);LED_Ctrl(LED_0, LED_OFF);break;}}
}


http://www.ppmy.cn/news/1272259.html

相关文章

阿里云对象存储OSS外网流出流量异常增多导致费用上升的解决方法

本文介绍在使用阿里云的对象存储 OSS服务过程中,外网流量消耗异常增多并导致异常的费用支出这一情况的问题发现、问题定位与几种不同的问题解决方法。 细细数来,写博客已经有近3的历史了,这成为了一项已经陪伴我大半人生的工作;也…

uniapp常用api讲解

Uniapp是一个基于Vue.js的跨平台开发框架,可以同时开发微信小程序、H5、App等多个平台的应用。下面是Uniapp常用的API讲解: Vue.js的API Uniapp采用了Vue.js框架,因此可以直接使用Vue.js的API。例如:v-show、v-if、v-for、compu…

贝蒂详解<string.h>哦~(用法与实现)

目录 引言: (一)字符函数和字符串函数 1.简介 2.strlen()函数 2.1用法 2.2实例 2.3 实现strlen() (1)计数法 (2)递归法 (3) 指针-指针 2.4sizeof和strlen()的区别 3.s…

CentOS新系统工具安装

时区设置 ## 查看当前时区 timedatectl | grep "Time zone" ## 查看时区列表 thiimedatectl list-timezones ## 设置时区 sudo timedatectl set-timezone Asia/ShanghaiCentOS7桌面怎么校准时间?(设置时区) 安装Docker 环境 # …

固态硬盘缓存和不缓存的区别

简单来说,带缓存的SSD固态硬盘性能更高,但由于断电后缓存上数据易丢失,而不带缓存的固态则是直接写入硬盘,安全性更高,两者在价格上区别较小,但带缓存的价格一般会高于不缓存的硬盘。 固态硬盘&#xff08…

Unity_使用FairyGUI搭建登录页面

Unity_使用FairyGUI搭建登录页面 1. 使用FairyGUI准备一个UI界面,例如:以下登录 2. 发布导出(发布路径设置为Unity的Asset下任何路径) 3. Unity编辑器安装FairyGUI包资源(在资源商店找见并存储为我的资源,…

《C++20设计模式》---桥接模式学习笔记

c20设计模式 第 7 章 桥接模式7.1 Pimpl模式7.2 桥接模式介绍7.3 总结7.4 代码 第 7 章 桥接模式 如果你一直关注C编译器(特别GCC, Clang和MSVC)的最新进展,那么可能已经注意到编译速度提高了。特别是,编译的体量越来…

深入解析 Spring 和 Spring Boot 的区别

目录 引言 1. 设计理念 1.1 Spring 框架的设计理念 1.2 Spring Boot 的设计理念 2. 项目配置 2.1 Spring 框架的项目配置 2.2 Spring Boot 的项目配置 3. 自动配置 3.1 Spring 框架的自动配置 3.2 Spring Boot 的自动配置 4. 微服务支持 4.1 Spring 框架的微服务支持…