ESP32 在低功耗模式下,如何利用 ULP 协处理器实现 GPIO 唤醒且不丢失 RTC 内存数据?

· 2 浏览

回答(4)

若需保留更多数据,可考虑使用RTC_NOINIT_ATTR段,避免初始化覆盖;同时,ULP程序本身也占用RTC内存,需规划好空间。
电源管理专家 · 2026-08-27
注意:GPIO唤醒时,ULP需设置`RTC_GPIO_PIN_REG`的`RTC_GPIO_PIN_INT_ENA`位,但ULP通常用轮询而非中断,确保采样周期足够短以响应快速变化。
嵌入式小兵 · 2026-08-27
补充:ULP唤醒后,CPU会从复位向量启动,但RTC内存数据保持,因此可在`app_main`中通过`RTC_DATA_ATTR`变量恢复状态,无需重新初始化。
低功耗老手 · 2026-08-27
在ESP32低功耗模式下,利用ULP协处理器实现GPIO唤醒并保持RTC内存数据的关键在于正确配置ULP程序、GPIO唤醒源和RTC内存的保持。首先,ULP协处理器可以在深度睡眠(Deep Sleep)期间运行,通过周期性地采样GPIO状态来检测唤醒条件。具体步骤:1) 编写ULP程序,使用RTC_GPIO寄存器(如RTC_GPIO_IN_REG)读取GPIO电平,并在条件满足时执行WAKE指令(如`WAKE`或`STOP`后触发唤醒)。2) 在ULP程序中,避免使用普通RAM,仅使用RTC内存(RTC_SLOW_MEM)存储变量,因为深度睡眠时普通RAM断电,而RTC内存保持供电。3) 配置GPIO为RTC功能(通过`rtc_gpio_pullup_en`和`rtc_gpio_pulldown_en`),并确保GPIO未被其他外设占用。4) 在进入深度睡眠前,调用`esp_sleep_enable_ulp_wakeup()`使能ULP唤醒,并设置`esp_deep_sleep_start()`。5) 唤醒后,检查`esp_sleep_get_wakeup_cause()`确认是ULP唤醒,然后从RTC内存读取数据。注意:ULP程序需编译为RTC内存中的二进制,且RTC内存数据在唤醒后保留,但需确保变量声明在RTC_DATA_ATTR或RTC_NOINIT_ATTR段中。实操建议:使用ESP-IDF的ULP协处理器工具链,参考官方示例`ulp_adc`或`ulp_gpio`,并测试功耗与唤醒延迟。
mcuku 阿沐 · 2026-08-27