2. ESP32-S3 麦克风音频采集与回放验证

任务目标

在 ESP32-S3 上通过 GPIO 控制板载 LED 的亮灭,并读取按键输入状态,实现“按下按键切换 LED 状态”的功能。本案例用于掌握 ESP-IDF 中 GPIO 的基本输入输出配置与轮询读取方法。

所需环境与依赖

  • 硬件:ESP32-S3-DevKitC-1 开发板(板载 RGB LED 与 Boot 按键)
  • 软件:ESP-IDF v5.x(需已配置好 ESP32-S3 编译环境)
  • 连接:开发板通过 USB 连接电脑,可正常烧录与查看串口日志

关键完整代码

以下代码为完整可编译的 ESP-IDF 工程源码,包含主程序入口与全部 GPIO 逻辑。将代码保存为 main.c,并配合最小工程结构(CMakeLists.txt 与 idf.py 默认配置)即可编译烧录。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define LED_GPIO      2      // 板载 RGB LED 的绿色通道(部分版本为 48,请按实际调整)
#define BUTTON_GPIO   0      // Boot 按键,按下为低电平

static const char *TAG = "gpio_demo";

void app_main(void)
{
    // 配置 LED 引脚为推挽输出
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << LED_GPIO),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE
    };
    gpio_config(&io_conf);

    // 配置按键引脚为输入,启用内部上拉(按键按下接地)
    io_conf.pin_bit_mask = (1ULL << BUTTON_GPIO);
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
    gpio_config(&io_conf);

    bool led_state = false;
    int last_button_level = 1;  // 上一次按键电平(1=未按下)

    ESP_LOGI(TAG, "GPIO demo started. Press Boot button to toggle LED.");

    while (1) {
        int current_level = gpio_get_level(BUTTON_GPIO);

        // 检测下降沿(按下瞬间),并做简单消抖
        if (current_level == 0 && last_button_level == 1) {
            vTaskDelay(pdMS_TO_TICKS(20));  // 消抖延时
            if (gpio_get_level(BUTTON_GPIO) == 0) {
                led_state = !led_state;
                gpio_set_level(LED_GPIO, led_state ? 1 : 0);
                ESP_LOGI(TAG, "LED state: %s", led_state ? "ON" : "OFF");
            }
        }
        last_button_level = current_level;
        vTaskDelay(pdMS_TO_TICKS(10));  // 轮询间隔
    }
}

工程配置与编译

在 ESP-IDF 环境中创建工程后,将上述代码放入 main/main.c,并确保 main/CMakeLists.txt 包含 idf_component_register(SRCS "main.c" INCLUDE_DIRS ".")。然后在工程根目录执行以下命令:

idf.py set-target esp32s3
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor   # 将 /dev/ttyUSB0 替换为实际串口设备

验证方法与判定标准

  1. 烧录成功后,串口监视器应输出 GPIO demo started... 日志。
  2. 按下开发板 Boot 按键(GPIO0),松开后 LED 状态应切换(亮→灭 或 灭→亮),同时串口输出对应的 LED state: ON/OFF 日志。
  3. 连续快速按动按键,每次按下松开都应触发一次状态切换,无漏触发或误触发。
  4. 若 LED 不亮,请检查 LED_GPIO 宏定义是否与你的开发板实际 LED 引脚一致(部分 DevKitC 板载 RGB LED 绿色通道为 GPIO2,部分版本为 GPIO48)。

常见问题

  • 按键无反应:确认按键引脚是否接内部上拉,且按下时确实接地(Boot 键默认接 GPIO0)。
  • LED 不亮:部分开发板 LED 为低电平点亮,若你的板载 LED 为共阳接法,需将 gpio_set_level 中的逻辑反转(即 led_state ? 0 : 1)。
  • 状态切换抖动:代码已包含 20ms 消抖,若仍抖动可适当增大延时。