搜索
bottom↓
回复: 0

《DNESP32S3使用指南-IDF版_V1.6》第十一章 KEY实验

[复制链接]

出0入234汤圆

发表于 2 小时前 | 显示全部楼层 |阅读模式
2.jpg
1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729
1.png
3.png

第十一章 KEY实验

       在上一章,我们详细讲解了GPIO的输出模式,并演示了如何利用它来控制LED的亮灭。而在本章中,我们将重点关注GPIO的输入模式配置,学会如何获取外部的输入信号,例如检测按键的状态。通过学习本章内容,开发者将能够掌握GPIO作为输入模式的使用方法,进一步扩展其在嵌入式系统开发中的应用能力。
       本章分为如下几个小节:
       11.1 独立按键基础知识
       11.2 硬件设计
       11.3 程序设计
       11.4 下载验证

       11.1 独立按键基础知识
       独立按键是一种简洁高效的输入设备,广泛应用于各类电子设备中,实现基础的用户交互功能。其工作原理主要基于机械开关的触发机制,当用户按下按键时,便能执行相应的操作。独立按键在尺寸、形状和颜色上都具有多样性,便于用户进行辨识和使用,满足不同场景下的需求。

       1,独立按键原理
       独立按键的原理主要依赖于机械触点和电气触点之间的相互作用。在未被按下时,触点保持分离状态,电路处于断开状态。然而,当用户按下按键时,在弹簧和导电片的共同作用下,触点会闭合,从而使电路连通。此时,微控制器能够检测到按键触发的信号,进而执行相应的操作。这种基于物理触点的设计使得独立按键既稳定又可靠,广泛应用于各种电子设备中。

       2,消抖措施
       机械按键在闭合与分开的过程中,由于机械振动(类似于弹簧效应)的存在,可能导致开关状态在短时间内频繁切换,这种现象被称为按键抖动。下图是独立按键抖动波形图。

第十一章 KEY实验609.png
图11.1.1 独立按键抖动波形图

       图中的按下抖动和释放抖动的时间一般为5~10ms,如果在抖动阶段采样,其不稳定状态可能出现一次按键动作被认为是多次按下的情况。为了避免抖动可能带来的误操作,我们要做的措施就是给按键消抖(即采样稳定闭合阶段)。
       为了消除这种抖动,我们通常采用软件消抖和硬件消抖两种主要方法:

       (1)软件消抖:主要是通过编程的方法,设定一个延迟或计时器,确保在一定的时间内只读取一次按键状态,避免抖动对程序的影响。

       (2)硬件消抖:在按键电路中加入元器件如电阻、电容组成的RC低通滤波器,对按键信号进行平滑处理,降低抖动的影响。

       我们例程中使用最简单的延时消抖。检测到按键按下后,一般进行10ms延时,用于跳过抖动的时间段,如果消抖效果不好可以调整这个10ms延时,因为不同类型的按键抖动时间可能有偏差。待延时过后再检测按键状态,如果没有按下,那我们就判断这是抖动或者干扰造成的;如果还是按下,那么我们就认为这是按键真的按下了。对按键释放的判断同理。

       11.2 硬件设计

       11.2.1 例程功能
       实验现象:按下BOOT按键可控制LED状态翻转。

       11.2.2 硬件资源
       1. LED
              LED-IO1
       2. 按键
              BOOT-IO0

       11.2.3 原理图
       本章实验使用的一个ESP32-S3开发板板载按键:BOOT按键,其于板载MCU的连接原理图,如下图所示:

第十一章 KEY实验1198.png
图11.2.3.1 按键与MCU的连接原理图

       从上面的原理图中可以看出,BOOT按键的一端连接到了电源负极,而另一端分别与MCU的BOOT引脚相连接,因此当按键被按下时,MCU对应的引脚都能够读取到低电平的状态,而当松开按键后,MCU对应的引脚读取到的电平状态却是不确定的,因此用于读取BOOT按键的BOOT引脚不仅要配置为输入模式,还需要配置成上拉。

       11.3 程序设计

       11.3.1 程序流程图
       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:

第十一章 KEY实验1487.png
图11.3.1.1 KEY实验程序流程图

       11.3.2 GPIO函数解析
       GPIO函数已在10.3.2章节中详细阐述,为避免重复,此处不再赘述。建议读者查阅第十章的函数解析章节,以获取更多关于GPIO函数的信息。

       11.3.3 KEY驱动解析
       在IDF版的02_key例程中,作者在01_key\components\BSP路径下新增了一个KEY文件夹,用于存放key.c和key.h这两个文件。其中,key.h文件负责声明KEY相关的函数和变量,而key.c文件则实现了KEY的驱动代码。下面,我们将详细解析这两个文件的实现内容。

       1,key.h文件
  1. /* 引脚定义 */
  2. #define BOOT_GPIO_PIN   GPIO_NUM_0

  3. /*IO操作*/
  4. #define BOOT            gpio_get_level(BOOT_GPIO_PIN)

  5. /* 按键按下定义 */
  6. #define BOOT_PRES       1       /* BOOT按键按下 */

  7. /* 函数声明 */
  8. void key_init(void);            /* 初始化按键 */
  9. uint8_t key_scan(uint8_t mode); /* 按键扫描函数 */
复制代码
       此文件的核心内容已较为明确,无需过多阐述。它主要定义了BOOT宏,用于获取IO0的状态,并声明了key_init和key_scan函数,以便外部文件能够调用这些函数。通过这些声明和定义,该文件为其他部分的代码提供了必要的接口和功能支持。

       2,key.c文件
       此文件中定义了两个函数,分别为key_init和key_scan。接下来,我将对这两个函数进行详细的解析。
       (1)key_init函数
  1. /**
  2. * @brief       初始化按键
  3. * @param       无
  4. * @retval      无
  5. */
  6. void key_init(void)
  7. {
  8.     gpio_config_t gpio_init_struct;

  9.     gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
  10.     gpio_init_struct.mode = GPIO_MODE_INPUT;                /* 输入模式 */
  11.     gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
  12.     gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE;  /* 失能下拉 */
  13.     gpio_init_struct.pin_bit_mask = 1ull << BOOT_GPIO_PIN;  /* BOOT按键引脚 */
  14.     gpio_config(&gpio_init_struct);                         /* 配置使能 */
  15. }
复制代码
       该函数主要配置IO0管脚为输入模式,这样就可以获取IO0的电平状态了。

       (2)key_scan函数
  1. /**
  2. * @brief       按键扫描函数
  3. * @param       mode:0 / 1, 具体含义如下:
  4. *              0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,
  5. *                  必须松开以后, 再次按下才会返回其他键值)
  6. *              1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)
  7. * @retval      键值, 定义如下:
  8. *              BOOT_PRES, 1, BOOT按下
  9. */
  10. uint8_t key_scan(uint8_t mode)
  11. {
  12.     uint8_t keyval = 0;
  13.     static uint8_t key_boot = 1;    /* 按键松开标志 */

  14.     if(mode)
  15.     {
  16.         key_boot = 1;
  17.     }

  18.     if (key_boot && (BOOT == 0))    /* 按键松开标志为1,且有任意一个按键按下了 */
  19.     {
  20.         vTaskDelay(10);             /* 去抖动 */
  21.         key_boot = 0;

  22.         if (BOOT == 0)
  23.         {
  24.             keyval = BOOT_PRES;
  25.         }
  26.     }
  27.     else if (BOOT == 1)
  28.     {
  29.         key_boot = 1;
  30.     }

  31.     return keyval;                  /* 返回键值 */
  32. }
复制代码
       此函数只有一个形参mode,用于设置按键是否支持连续按下模式。当mode为0时,表示按键不支持连续按下;反之,则支持连续按下。值得注意的是,该函数内部已经对按键进行了消抖延时处理,因此,在其他地方调用此函数时,无需再进行额外的按键消抖操作。

       11.3.4 CMakeLists.txt文件
       打开本实验BSP下的CMakeLists.txt文件,其内容如下所示
  1. set(src_dirs
  2.             KEY
  3.             LED)

  4. set(include_dirs
  5.             KEY
  6.             LED)

  7. set(requires
  8.             driver)

  9. idf_component_register(SRC_DIRS ${src_dirs}
  10. INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})

  11. component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)
复制代码

       上述的红色KEY驱动需要由开发者自行添加,以确保KEY驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了KEY驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。

       11.3.5 实验应用代码
       打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。
  1. /**
  2. * @brief       程序入口
  3. * @param       无
  4. * @retval      无
  5. */
  6. void app_main(void)
  7. {
  8.     uint8_t key;
  9.     esp_err_t ret;
  10.    
  11.     ret = nvs_flash_init();     /* 初始化NVS */

  12. if (ret == ESP_ERR_NVS_NO_FREE_PAGES
  13. || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  14.     {
  15.         ESP_ERROR_CHECK(nvs_flash_erase());
  16.         ret = nvs_flash_init();
  17.     }

  18.     led_init();                 /* 初始化LED */
  19.     key_init();                 /* KEY初始化 */

  20.     while(1)
  21.     {
  22.         key = key_scan(0);      /* 获取键值 */

  23.         switch (key)
  24.         {
  25.             case BOOT_PRES:     /* BOOT被按下 */
  26.             {
  27.                 LED_TOGGLE();   /* LED状态翻转 */
  28.                 break;
  29.             }
  30.             default:
  31.             {
  32.                 break;
  33.             }
  34.         }

  35.         vTaskDelay(10);
  36.     }
  37. }
复制代码
       可以看到应用代码中,在初始化完LED和按键后,就进入了一个while循环,在循环中,每间隔10毫秒就调用key_scan()函数扫描以此按键的状态,如果扫描到BOOT按键被按下,则反转对应LED的亮灭状态。

       11.4 下载验证
       在完成编译和烧录操作后,可以看到板子上的LED是处于亮起的状态,若此时按下并释放一次BOOT按键,则能够看到LED的亮灭状态发生了一次翻转,与预期的实验现象效果相符。

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-16 17:50

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表