【ESP32】ESP-IDF开发 | GPIO通用输入输出+LED点灯和按键输入例程

1. 简介

        ESP32芯片有34个物理GPIO pad,每个GPIO pad都可用作一个通用IO或连接一个内部的外设信号。IO_MUX、RTC IO_MUX和GPIO交换矩阵用于将信号从外设传输至GPIO pad。

        从上面看到,每个pad可以配置成GPIO功能(连接GPIO交换矩阵)或者直连功能(旁路GPIO交换矩阵),功能的切换通过IO_MUX来实现。

        ESP32一共有162个外设输入信号和176个外设输出信号,要使用某个外设,就要把外设信号连接到对应的GPIO pad上,这个功能就是由GPIO交换矩阵来实现的。

        直连功能和GPIO功能有什么不同呢?快速信号如以太网、SDIO、SPI、JTAG、UART 等,通过旁路 GPIO 交换矩阵可以实现更好的高频数字特性,所以高速信号会直接通过 IO_MUX 输入和输出。

        ESP32除了有物理pad还有RTC pad,这些pads通过RTC IO_MUX可以配置成RTC GPIO功能,这些管脚主要在低功耗的模式下工作,实现低功耗功能。

        但要注意的是,虽然ESP32有34个物理pad,但并不是所有的pad都能任由用户控制或全功能的,下面列出一些开发时要注意的管脚:

  1. GPIO34-39,这几个管脚只有输入功能,没有输出功能,而且没有上下拉配置;
  2. GPIO6-11,如果你的模组带NOR Flash的话,这几个管脚是负责Flash的通信的,不能使用;
  3. GPIO12-15,这几个是JTAG的调试管脚,GPIO12是默认下拉的,GPIO15是默认上拉的,使用时要注意;
  4. GPIO1和GPIO3,这两个是芯片的调试串口和下载串口,不能用作其他使用;
  5. GPIO0、GPIO2和GPIO5,这几个是芯片的strapping管脚,GPIO0默认上拉,GPIO2默认下拉,GPIO5默认上拉,使用时要注意。

2. 例程

2.1 LED点灯

        这个例程实现一个点灯的代码,LED灯每隔一秒改变一次状态。

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"

void app_main()
{
    gpio_config_t gpio_cfg = {0};

    gpio_cfg.mode = GPIO_MODE_OUTPUT;
    gpio_cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
    gpio_cfg.pull_up_en = GPIO_PULLUP_DISABLE;
    gpio_cfg.intr_type = GPIO_INTR_DISABLE;
    gpio_cfg.pin_bit_mask = (1 << GPIO_NUM_2);
    gpio_config(&gpio_cfg);

    while (1)
    {
        gpio_set_level(GPIO_NUM_2, 1);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        gpio_set_level(GPIO_NUM_2, 0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

         GPIO的初始化使用gpio_config一个函数即可,结构体里面配置模式(mode)、下拉(pull_down_en)、上拉(pull_up_en)、中断使能(intr_type)、管脚映射(pin_bit_mask)。

        管脚映射是用一个uint64_t实现的,每个bit代表一个管脚,所以要将管脚号左移对应位数来使能对应管脚。

        主循环里面使用gpio_set_level函数来控制GPIO输出,因为IDF框架是基于FreeRTOS的,所以延时可以直接调用vTaskDelay实现。

        系统启动后的打印如下,可以看到最后一行打印了我们管脚的配置信息,此时开发板上的LED灯就在闪烁了。

2.2 按键输入

        这个例程配置管脚为输入模式,接收按键的输入信号。例程使用的是开发板的IO0管脚作为按键输入。

#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "esp_log.h"

#define TAG "app"

void app_main()
{
    gpio_config_t gpio_cfg = {0};

    gpio_cfg.mode = GPIO_MODE_INPUT;
    gpio_cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
    gpio_cfg.pull_up_en = GPIO_PULLUP_ENABLE;
    gpio_cfg.intr_type = GPIO_INTR_DISABLE;
    gpio_cfg.pin_bit_mask = (1 << GPIO_NUM_0);
    gpio_config(&gpio_cfg);

    while (1) {
        if (0 == gpio_get_level(GPIO_NUM_0)) {

            /* 软件去抖 */
            while (0 == gpio_get_level(GPIO_NUM_0)) {
                vTaskDelay(20 / portTICK_PERIOD_MS);
            }
            
            ESP_LOGI(TAG, "Key pressed");
        }

        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}

        GPIO的配置和前面差不多,只是模式改成输入即可,上下拉可以根据自己的开发板设置,我这里设置为上拉。

        主循环使用gpio_get_level不断查看按键状态,检测到按键按下后会经过一个软件去抖处理,防止多次触发,最后就是打印一个log信息。

        需要注意主循环最后的这个延时必须要有!!!因为IDF是默认开启看门狗的,看门狗的喂狗函数在空闲任务里面,而主任务的优先级是高于空闲任务的;如果不加延时,空闲任务会一直运行不了,导致看门狗超时,系统重启。

### 使用ESP-IDF处理MJPEG视频 对于希望利用ESP-IDF框架来处理来自摄像头的MJPEG视频流的情况,可以采用如下方式实现: #### 初始化摄像头并配置参数 为了能够顺利接收处理MJPEG格式的数据,在初始化阶段需确保正确设置了摄像头的相关属性。这通常涉及到设置图像分辨率、帧率以及最重要的——像素格式为`MJPG`。 ```c #include "esp_camera.h" camera_config_t config; config.pin_pwdn = CAM_PIN_PWDN; config.pin_reset = CAM_PIN_RESET; config.pin_xclk = CAM_PIN_XCLK; // ...其他必要的引脚定义... config.pixel_format = PIXFORMAT_JPEG; // 设置为JPEG模式即代表使用MJPEG ``` #### 创建HTTP服务器用于传输数据 一旦成功获取到了MJPEG格式的画面,则可通过创建一个简单的Web Server将这些画面实时推送出去供客户端访问查看。这里推荐使用ESP-IDF自带的支持库简化操作过程。 ```c httpd_handle_t server; static esp_err_t stream_handler(httpd_req_t *req){ camera_fb_t *fb = NULL; fb = esp_camera_fb_get(); // 获取一帧图像 httpd_resp_set_type(req, "image/jpeg"); httpd_resp_send_chunk(req, (const char *)fb->buf, fb->len); esp_camera_fb_return(fb); // 返回缓冲区给驱动程序以便重复利用 return ESP_OK; } void start_stream_server(){ httpd_config_t config = HTTPD_DEFAULT_CONFIG(); ... } ``` 上述代码片段展示了如何通过ESP32内置的Camera模块配合HTTP服务端口完成基本功能[^1]。值得注意的是,当提到具体到ESP-IDF环境下的实践时,还需要考虑硬件资源分配、内存管理等因素以保障系统的稳定性效率。 针对不同应用场景可能还需进一步调整优化策略;例如增加缓存机制提高响应速度或者引入多线程技术增强并发能力等措施都可以有效提升整体性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马浩同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值