第八章 KEY实验
上一章,我们介绍了ESP32-S3的IO如何作为输出功能,实现LED闪烁。本章,我们将向大家介绍如何使用 ESP32-S3的IO口作为输入。我们将利用板载的boot按键,来控制板载的LED灯亮灭。通过本章的学习,我们将了解到ESP32-S3的IO口作为输入口的使用方法。 本章分为如下几个小节: 8.1 GPIO输入功能使用 8.2 硬件设计 8.3 软件设计 8.4 下载验证
8.1 GPIO输入功能使用 8.1.1 GPIO输入模式介绍 首先回顾一下:在上一章也提及到pinMode函数,要对数字I/O进行检测,首先把I/O设置为输入模式,然后使用数字I/O检测函数为digitalRead函数检测外部电平状态。当外部输入高电平时,返回值为1;当外部输入低电平时,返回值为0。 pinMode函数设置I/O为输入,有三种选择:INPUT、INPUT_PULLUP、INPUT_PULLDOWN。这里简单设置的依据就跟这个按键电路相关。当我们存在上拉或者下拉按键电路的情况时,可以直接选择INPUT;如果当前的按键电路需要内部上拉电阻,这时候选择INPUT_PULLUP;如果当前的按键电路需要内部下拉电阻时,这时候选择INPUT_PULLDOWN。 在这里,简单介绍一下上拉电阻电路、下拉电阻电路、内部上拉电路和内部下拉电路。 上拉电阻电路,如下图所示。 图8.1.1.1 上拉电阻电路图 当按键开关断开时,即没有被按下时,ESP32S3的IO0通过电阻和3.3V电源相连接,产生高电平,digitalRead(0)函数的返回值为1。当按键开关闭合时,即按下按键时,ESP32S3的IO0的电压和地相连接,产生低电平,digitalRead(0)函数的返回值为0。电路中的1KΩ电阻成为上拉电阻。 下拉电阻电路,如下图所示。 图8.1.1.2 下拉电阻电路图 当按键开关断开时,即没有被按下时,ESP32S3的IO0通过电阻和地相连接,产生低电平,digitalRead(0)函数的返回值为0。当按键开关闭合时,即按下按键时,ESP32S3的IO0的电压和电源3.3V相连接,产生高电平,digitalRead(0)函数的返回值为1。电路中的1KΩ电阻成为下拉电阻。 当数字输入引脚的工作模式设置为INPUT时,读取按键值,一定要在电路中设置一个上拉电阻或者下拉电阻,电阻的阻值一般可以为1~10KΩ。采用上拉电阻时,当按键断开时digitalRead(0)函数的返回值为1。采用下拉电阻时,当按键断开时,digitalRead(0)函数的返回值为0。 内部上拉电阻电路,除了上述的两种电路外,在ESP32S3控制器内部还集成了上拉电阻,通过在pinMode()函数中设置mode参数为INPUT_PULLUP来启动内部上拉电阻。 启动控制器内部的上拉电阻后,按键开关电路就可以省略外接电阻。 内部上拉电阻电路,如下图所示。 图8.1.1.3 内部上拉电阻电路 从上图可以看出,当开关断开时,digitalRead(0)函数的返回值为1;当开关闭合时,digitalRead(0)函数的返回值为0。 当采用内部上拉电阻电路时,按键的一端和数字引脚相连,另外一端和地相连。 内部下拉电阻电路,在ESP32S3控制器内部除了集成上拉电阻,还有下拉电阻,通过在pinMode()函数中设置mode参数为INPUT_PULLDOWN来启动内部下拉电阻。 启动控制器内部的下拉电阻后,按键开关电路就可以省略外接电阻。 内部下拉电阻电路,如下图所示。 图8.1.1.4 内部下拉电阻电路 从上图可以看出,当开关断开时,digitalRead(0)函数的返回值为0;当开关闭合时,digitalRead(0)函数的返回值为1。 当采用内部下拉电阻电路时,按键的一端和数字引脚相连,另外一端和VCC相连。 8.1.2 独立按键简介 几乎每个开发板都会板载有独立按键,因为按键用处很多。常态下,独立按键是断开的,按下的时候才闭合。每个独立按键会单独占用一个IO口,通过IO口的高低电平判断按键的状态。但是按键在闭合和断开的时候,都存在抖动现象,即按键在闭合时不会马上就稳定的连接,断开时也不会马上断开。这是机械触点,无法避免。独立按键抖动波形图如下: 图8.1.2.1 独立按键抖动波形图 图中的按下抖动和释放抖动的时间一般为5~10ms,如果在抖动阶段采样,其不稳定状态可能出现一次按键动作被认为是多次按下的情况。为了避免抖动可能带来的误操作,我们要做的措施就是给按键消抖(即采样稳定闭合阶段)。消抖方法分为硬件消抖和软件消抖,我们常用软件的方法消抖。 软件消抖:方法很多,我们例程中使用最简单的延时消抖。检测到按键按下后,一般进行10ms延时,用于跳过抖动的时间段,如果消抖效果不好可以调整这个10ms延时,因为不同类型的按键抖动时间可能有偏差。待延时过后再检测按键状态,如果没有按下,那我们就判断这是抖动或者干扰造成的;如果还是按下,那么我们就认为这是按键真的按下了。对按键释放的判断同理。 硬件消抖:利用RC电路的电容充放电特性来对抖动产生的电压毛刺进行平滑出来,从而实现消抖,但是成本会更高一点,本着能省则省的原则,我们推荐使用软件消抖即可。 8.2 硬件设计 1. 例程功能 通过开发板上的boot独立按键实现LED的亮灭。 2. 硬件资源 1)LED灯 LED-IO1 2)独立按键 BOOT-IO0 3. 原理图 独立按键硬件部分的原理图,如下图所示。 图8.3.1 独立按键与ESP32-S3连接原理图 这里需要注意的是:BOOT设计为采样到按键另一端的低电平为有效电平。 8.3 软件设计 8.3.1 程序流程图 下面看看本实验的程序流程图: 图8.3.1.1 程序流程图 8.3.2 程序解析 1. key驱动代码这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。KEY驱动源码包括两个文件:key.cpp和key.h。 下面我们先解析key.h的程序,我们把它分两部分功能进行讲解。 由硬件设计小节,我们知道KEY按键在硬件上连接到IO0,我们做了下面的引脚定义。 /* 引脚定义 */ #define KEY_PIN 0 /* 开发板上KEY连接到GPIO0引脚 */ 为了后续对KEY按键进行便捷的操作,我们为KEY按键操作函数做了下面的定义。 /* 宏函数定义 */ #define KEY digitalRead(KEY_PIN) /* 读取KEY引脚的状态 */ KEY是读取对应按键状态的宏定义。用digitalRead函数实现,该函数返回值就是IO口的状态,0或1,代表的是低电平或高电平。 下面我们再解析key.cpp的程序,这里只有一个函数key_init,这是KEY按键的初始化函数,其定义如下: /** * @param 无 * @retval 无 */ void key_init(void) { /* 结合原理图设计,按键没有按下时,KEY引脚检测到的是高电平 */ pinMode(KEY_PIN, INPUT_PULLUP); /* 设置key引脚为上拉输入模式 */ } KEY按键的引脚设置为上拉输入模式。默认情况,读取到的是高电平。 2. 02_key.ino代码在02_key.ino里面编写如下代码: #include "led.h" #include "key.h" /** * @brief 当程序开始执行时,将调用setup()函数,通常用来初始化变量、函数等 * @param 无 * @retval 无 */ void setup() { led_init(); /* LED初始化 */ key_init(); /* KEY初始化 */ } /** * @brief 循环函数,通常放程序的主体或者需要不断刷新的语句 * @param 无 * @retval 无 */ void loop() { if (KEY == 0) /* 读取KEY状态,如果按下KEY */ { delay(10); if (KEY == 0) { LED(0); /* LED引脚输出接低电平,点亮 */ } } else /* 读取KEY状态,如果KEY没有按下 */ { LED(1); /* LED引脚输出接高电平,熄灭 */ } } 在setup函数中,除了要调用key_init函数对KEY进行初始化,还要调用led_init对LED进行初始化。接下来,在loop函数中,当按键被按下时,会调用delay函数等待10毫秒实现消抖作用,然后再次确认按键状态,如果按键确实被按下,点亮LED。如果按键没有被按下时,就会熄灭LED。然后程序进入检测按键是否按下的循环中。 8.4 下载验证 下载完之后,通过BOOT按键来控制LED灯的亮灭状态。
|