1、概述:为什么需要 RTC GPIO 按键唤醒?
ESP32 的 Deep-sleep(深度睡眠)模式 是低功耗场景的核心功能——此时芯片会关闭 CPU、内存等核心模块,仅保留 RTC(实时时钟)控制器和 RTC GPIO 引脚供电,功耗可低至微安级。
而 RTC GPIO 作为深度睡眠中唯一能检测外部信号的引脚,其核心作用有二:
- 作为输入时:检测电平变化(如按键按下),触发 RTC 控制器唤醒芯片;
- 作为输出时:深度睡眠中保持固定电平(非本文重点)。
按键唤醒的本质,就是通过 RTC GPIO 检测按键触发的电平变化,实现 “深度睡眠 → 唤醒执行任务 → 重新睡眠” 的低功耗循环。
2、 ESP32 支持的 RTC GPIO
并非所有 ESP32 引脚都支持 RTC 功能,仅以下引脚可用于按键唤醒(不同模组可能略有差异,以实际 datasheet 为准):
提示:GPIO34~GPIO39 仅输入模式,无内部上拉/下拉,需外接硬件电阻;其他 RTC GPIO 可启用内部电阻,简化硬件设计。

3、实战配置:按键唤醒完整实现
3.1 硬件接线(以 GPIO4 为例)
| ESP32 引脚 | 外部元件 | 说明 |
|---|---|---|
| GPIO4 | 按键一端 | 按键触发引脚 |
| 按键另一端 | GND | 按下时拉低 GPIO4 电平 |
| GPIO4 | (可选)4.7kΩ 上拉电阻 | 无内部上拉时需外接(如 GPIO34) |
若启用内部上拉(如 GPIO4),可省略外部上拉电阻,简化电路。
3.2 软件配置:核心代码实现
步骤 1:引脚初始化与睡眠配置
#include "driver/rtc_io.h"
#include "esp_sleep.h"
#include "esp_log.h"
// 配置参数(根据实际接线修改)
#define WAKE_PIN GPIO_NUM_4 // 选择支持的 RTC GPIO
#define TRIG_LEVEL 0 // 0=低电平唤醒(按键接GND),1=高电平唤醒(按键接VDD)
static const char *TAG = "KEY_WAKE";
// 初始化 RTC GPIO 并进入深度睡眠
void key_wake_enter_sleep(void) {
// 1. 重置引脚:清除历史配置(顺序不可乱)
rtc_gpio_deinit(WAKE_PIN); // 先释放 RTC 模式配置
gpio_reset_pin(WAKE_PIN); // 再重置普通 GPIO 配置
// 2. 初始化 RTC GPIO 为输入模式
rtc_gpio_init(WAKE_PIN);
rtc_gpio_set_direction(WAKE_PIN, RTC_GPIO_MODE_INPUT_ONLY);
// 3. 配置上拉/下拉(根据硬件选择)
if (WAKE_PIN >= GPIO_NUM_34 && WAKE_PIN <= GPIO_NUM_39) {
// GPIO34~39 无内部电阻,直接禁用
rtc_gpio_pullup_dis(WAKE_PIN);
rtc_gpio_pulldown_dis(WAKE_PIN);
} else {
// 其他 RTC GPIO:启用内部上拉(配合按键接GND)
rtc_gpio_pullup_en(WAKE_PIN); // 启用内部上拉
rtc_gpio_pulldown_dis(WAKE_PIN); // 禁用下拉,避免冲突
}
// 4. 配置 EXT0 唤醒源(单个 RTC GPIO 触发)
esp_err_t err = esp_sleep_enable_ext0_wakeup(WAKE_PIN, TRIG_LEVEL);
if (err != ESP_OK) {
ESP_LOGE(TAG, "唤醒源配置失败!错误码: 0x%x", err);
return;
}
// 5. 进入深度睡眠
ESP_LOGI(TAG, "已进入深度睡眠,按按键唤醒...");
esp_deep_sleep_start(); // 执行后芯片暂停,等待唤醒
}
步骤 2:唤醒后检测与任务执行
void app_main(void) {
// 1. 检测唤醒原因(唤醒后芯片重启,需重新判断)
esp_sleep_wakeup_cause_t wake_cause = esp_sleep_get_wakeup_cause();
// 2. 区分唤醒源,执行对应任务
switch (wake_cause) {
case ESP_SLEEP_WAKEUP_EXT0:
// 按键唤醒:执行任务(如读取传感器、上报数据)
ESP_LOGI(TAG, "按键唤醒成功!开始执行任务...");
// TODO:添加你的业务逻辑(如调用传感器读取函数、发送HTTP请求)
break;
case ESP_SLEEP_WAKEUP_UNDEFINED:
// 首次上电/复位:仅打印日志
ESP_LOGI(TAG, "首次上电/复位,无唤醒原因");
break;
default:
// 其他唤醒源(如定时器):按需处理
ESP_LOGI(TAG, "其他唤醒源,原因码: %d", wake_cause);
break;
}
// 3. 任务执行完成后,重新进入深度睡眠
key_wake_enter_sleep();
}
6272

被折叠的 条评论
为什么被折叠?



