2·ESP32 您所在的位置:网站首页 esp开关是干什么用的 2·ESP32

2·ESP32

2024-07-01 09:17| 来源: 网络整理| 查看: 265

【写在前面】经过了点灯→定时器点灯→PWM点灯的学习之后,逐渐开始对ESP32 C3整体的框架有了一定认识【 点灯模块链接指路:http://t.csdn.cn/xOBmI】也掌握了一些理解和学习代码的思路,这一章咱们聊一聊按键的控制。

目录

GPIO输出与按键控制

level 1:从一个朴实无华的点按开始

level 2:引入队列、中断——实现按键控制2.0

优化代码、引入队列,实现多按键控制

通过线程的方式完成中断

小结

GPIO输出与按键控制 level 1:从一个朴实无华的点按开始

        首先咱们了解下按键的硬件板块(以我手上的板子为例),可以发现按键按下电路导通对应低电平。

        于是咱们可以使用最好理解的方法,从点按开始,光速上手按键模块:

#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "sdkconfig.h" #define KEY1_IO 9 #define KEY2_IO 8 #define LED_RED_IO 10 //咱们借用红灯作为按键指示灯 #define LED_ON 0 //这个板子是共阳极,低电平亮 #define LED_OFF 1 void initKey() //按键初始化(选择和设置为IO输入) { gpio_pad_select_gpio(KEY1_IO); gpio_pad_select_gpio(KEY2_IO); gpio_set_direction(KEY1_IO, GPIO_MODE_INPUT); gpio_set_direction(KEY2_IO, GPIO_MODE_INPUT); } void initLed() //因为灯咱们也用到了,所以也要初始化 { gpio_pad_select_gpio(LED_RED_IO); gpio_set_direction(LED_RED_IO, GPIO_MODE_OUTPUT); } int key_read_key1(void) //一个很笨的方法,直到松开才触发下一步,否则一直等待松开 { if(gpio_get_level(KEY1_IO)==0) { while (gpio_get_level(KEY1_IO)==0) { vTaskDelay(1); } return 1; } return 0; } int key_read_key2(void) //同上 { if(gpio_get_level(KEY2_IO)==0) { while (gpio_get_level(KEY2_IO)==0) { vTaskDelay(1); } return 1; } return 0; } void main() { initKey(); initLed(); while(1) //主函数一定要while(1),不然刚通电程序就结束了 { if(key_read_key1()) gpio_set_level(LED_RED_IO, LED_ON); if(key_read_key2()) gpio_set_level(LED_RED_IO, LED_OFF); } }

        编译,烧录,监视一气呵成~ level 1轻松秒杀,那要不要试下长按呢?

        想实现长按其实也挺简单的,基于level1的代码简单魔改就能实现,只需要引入"esp_system.h"中的函数esp_timer_get_time(),可以获取内置定时器当时的时间,我们可以用这个作为flag,判断低电平状态和高电平的时间差。代码如下:

#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "sdkconfig.h" #include "esp_system.h" #define KEY1_IO 9 #define KEY2_IO 8 #define LED_RED_IO 10 #define LED_ON 0 #define LED_OFF 1 void initKey() //和短按无变化,具体注释看短按 { gpio_pad_select_gpio(KEY1_IO); gpio_pad_select_gpio(KEY2_IO); gpio_set_direction(KEY1_IO, GPIO_MODE_INPUT); gpio_set_direction(KEY2_IO, GPIO_MODE_INPUT); } void initLed() //相比短按无变化,具体注释看短按 { gpio_pad_select_gpio(LED_RED_IO); gpio_set_direction(LED_RED_IO, GPIO_MODE_OUTPUT); } void key_read_key1(void) // //相比短按,引入了flag和 { int flag = 0; if(gpio_get_level(KEY1_IO)==0) { flag = esp_timer_get_time(); while(gpio_get_level(KEY1_IO)==0) { vTaskDelay(1); } flag = esp_timer_get_time() - flag; if(flag > 500*1000) gpio_set_level(LED_RED_IO, LED_ON); else gpio_set_level(LED_RED_IO, LED_OFF); } } void app_main() { initKey(); initLed(); while (1) { key_read_key1(); } }

        恭喜,如果上面的代码基本理解了,就已经可以做出一些小的模块了。但,这就满足了吗?

level 2:引入队列、中断——实现按键控制2.0

        上面的方法用于实现按键控制,虽然很好理解,但在功能上总是不大理想的,如果只是考试还好,在一个具体的项目工程中,这种代码比较冗余且不利于后续的拓展,此时就需要我们更进一步,引入队列、线程、中断、回调的概念,来实现框架化、模块化的按键控制2.0。

        对于入门来说,需要注意的地方其实还是不少,但是有了level1 的信心,level2 开始上点难度总不过分吧qwq,本文的所有代码我都统一了风格,可以通过比较的方式看看为了实现新功能新增了什么,改动了什么。

优化代码、引入队列,实现多按键控制 怎么样实现按键不松手就能输出一个按键长按?拒绝重复if else ,如何简化多个按键之间的代码? #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "freertos/queue.h" #include "esp_system.h" //多用了几个新的头文件 #include "sdkconfig.h" #define KEY1_IO 9 #define KEY2_IO 8 #define LED_RED_IO 10 //咱们借用红灯作为按键指示灯key1 #define LED_BLUE_IO 6 //再用一个蓝灯指示key2 #define LED_ON 0 //这个板子是共阳极,低电平亮 #define LED_OFF 1 static xQueueHandle gpio_evt_queue = NULL; //句柄地址先设置为0,点灯的文章中解释过 void IRAM_ATTR gpio_isr_handler(void *arg) //创建了一个中断回调函数 { uint32_t gpio_num = (u_int32_t) arg; xQueueSendFromISR(gpio_evt_queue,&gpio_num,NULL); //插入一个中断到队列中 } void initLed() //因为灯咱们也用到了,所以也要初始化 { gpio_pad_select_gpio(LED_RED_IO); gpio_set_direction(LED_RED_IO, GPIO_MODE_OUTPUT); gpio_set_level(LED_RED_IO, LED_OFF); gpio_pad_select_gpio(LED_BLUE_IO); gpio_set_direction(LED_BLUE_IO, GPIO_MODE_OUTPUT); gpio_set_level(LED_BLUE_IO, LED_OFF); } void initKey() //这里和上面的代码变化很大,是另一种配置IO口的方法 { gpio_config_t io_conf; //这边赋值的方式不够简洁,但是好理解 io_conf.intr_type = GPIO_INTR_ANYEDGE; //上升下降沿中断均可触发 io_conf.pull_up_en = 1; //上拉使能 io_conf.mode = GPIO_MODE_INPUT; //io口输入模式 io_conf.pin_bit_mask = (1


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有