3. 按键控制LED

按键控制LED 学习卡片

任务目标

使用ESP-IDF开发环境,通过GPIO读取按键输入状态,实现按键按下时切换LED的亮灭状态。本案例使用开发板上的板载按键和LED,无需额外硬件连接。

硬件准备

  • ESP32开发板(如ESP32-DevKitC、ESP32-S3-DevKitC等)
  • 板载按键(通常连接GPIO0,按下为低电平)
  • 板载LED(通常连接GPIO2,高电平点亮)

不同开发板的按键和LED引脚可能不同,请根据实际开发板原理图调整BUTTON_GPIO和LED_GPIO宏定义。

完整代码

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

#define BUTTON_GPIO  0   // 按键引脚(按下为低电平)
#define LED_GPIO     2   // LED引脚(高电平点亮)

static const char *TAG = "button_led";

// 软件消抖延时
#define DEBOUNCE_MS  50

void app_main(void)
{
    gpio_config_t io_conf = {};

    // 配置按键为输入,启用上拉电阻
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pin_bit_mask = (1ULL << BUTTON_GPIO);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    // 配置LED为推挽输出
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = (1ULL << LED_GPIO);
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);

    // 初始状态:LED熄灭
    gpio_set_level(LED_GPIO, 0);

    int last_button_state = 1;  // 上一次按键状态(1=未按下)
    int led_state = 0;          // 当前LED状态(0=灭,1=亮)

    ESP_LOGI(TAG, "按键控制LED示例已启动");

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

        // 检测下降沿(按下瞬间),并做软件消抖
        if (current_state == 0 && last_button_state == 1) {
            vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_MS));
            // 消抖后再次确认按键确实被按下
            if (gpio_get_level(BUTTON_GPIO) == 0) {
                led_state = !led_state;
                gpio_set_level(LED_GPIO, led_state);
                ESP_LOGI(TAG, "按键按下,LED状态切换为: %s", led_state ? "亮" : "灭");
            }
        }

        last_button_state = current_state;
        vTaskDelay(pdMS_TO_TICKS(10));  // 轮询间隔10ms
    }
}

项目配置与编译烧录

  1. 创建ESP-IDF工程:将上述代码保存为项目main目录下的main.c,并确保CMakeLists.txt中已包含idf_component_register(SRCS "main.c" INCLUDE_DIRS ".")。
  2. 在项目根目录执行以下命令完成编译与烧录:
idf.py set-target esp32   # 根据实际芯片选择目标
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor   # 将串口设备替换为实际端口

验证方法

  1. 烧录成功后,观察开发板LED初始状态为熄灭。
  2. 按下按键并松开,LED应点亮;再次按下并松开,LED应熄灭。每次按下切换一次状态。
  3. 在串口监视器中应看到类似日志输出:按键按下,LED状态切换为: 亮(或灭)。
  4. 快速连续按动按键,LED状态应稳定切换,无抖动导致的误触发。

通过标准:每次按下按键,LED状态可靠翻转一次,串口日志与LED状态一致,且无抖动误触发。

关键说明

  • 代码采用轮询方式读取GPIO电平,通过检测下降沿(高电平变为低电平)识别按键按下动作。
  • 软件消抖延时50ms,可有效滤除机械按键抖动;若按键响应不灵敏可适当减小,若仍有抖动可增大至80ms。
  • 按键使用内部上拉电阻,按下时引脚为低电平;若开发板按键为按下接高电平,需将pull_up_en改为0并配置下拉电阻,同时反转判断逻辑。