2. GPIO 控制与按键输入
任务目标
在 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 替换为实际串口设备
验证方法与判定标准
- 烧录成功后,串口监视器应输出
GPIO demo started...日志。 - 按下开发板 Boot 按键(GPIO0),松开后 LED 状态应切换(亮→灭 或 灭→亮),同时串口输出对应的
LED state: ON/OFF日志。 - 连续快速按动按键,每次按下松开都应触发一次状态切换,无漏触发或误触发。
- 若 LED 不亮,请检查
LED_GPIO宏定义是否与你的开发板实际 LED 引脚一致(部分 DevKitC 板载 RGB LED 绿色通道为 GPIO2,部分版本为 GPIO48)。
常见问题
- 按键无反应:确认按键引脚是否接内部上拉,且按下时确实接地(Boot 键默认接 GPIO0)。
- LED 不亮:部分开发板 LED 为低电平点亮,若你的板载 LED 为共阳接法,需将
gpio_set_level中的逻辑反转(即led_state ? 0 : 1)。 - 状态切换抖动:代码已包含 20ms 消抖,若仍抖动可适当增大延时。