低功耗模式

罗大富 BigRich大约 5 分钟ESP32Python

实验原理

超低功耗协处理器(ULP Coprocessor)是一种功耗极低的协处理器设备,可在主系统级芯片(SoC)系统进入 Deep-sleep 状态时保持上电,允许开发者通过存储在 RTC 中的专用程序,访问外围设备、内部传感器及 RTC 寄存器。ULP 协处理器的主要应用场景包括一些需要在保证最低功耗的情况下,通过外部活动或计时器(或两者兼有)唤醒 CPU 的应用。

主要特性:

  • 可访问最多 8 KB SRAM RTC 慢速内存,储存指令和数据
  • 采用 8 MHz RTC_FAST_CLK 时钟频率
  • 支持正常模式和 Deep-sleep 模式
  • 可唤醒 CPU 或向 CPU 发送中断
  • 可访问外围设备、内部传感器及 RTC 寄存器
  • 采用 4 个 16 位通用寄存器 (R0 - R3),进行数据操作和内存访问
  • 采用 1 个 8 位阶段计数器寄存器 Stage_cnt,可通过 ALU 指令进行操作并用于 JUMP 指令

查询 ESP32 的设计参考手册,可以发现 ESP32 的电源模式有5种:Active、Modem Sleep、Light Sleep、Deep Sleep、Hibernation, 相关的设定流程如下:

  1. Active 活动模式:在此模式下,整个芯片上电,芯片可以接收、传输数据,耗电量最大的模式。
  1. Modem Sleep调制解调器睡眠模式:在此模式下,CPU 可以运行,但禁用 Wi-Fi 蓝牙无线电。此模式可用于需要 CPU 工作的应用程序,如 PWM。它使 Wi-Fi 调制解调器电路在与 Wi-Fi AP(接入点)连接时关闭,无数据传输以优化功耗。
  1. Light Sleep 轻度睡眠模式:在此模式下,CPU 和所有外围设备都暂停。任何唤醒(如外部中断)都会唤醒芯片。在没有数据传输的情况下,可以关闭 Wi-Fi 调制解调器电路并暂停 CPU 以节省功耗。
  1. Deep Sleep 深度睡眠模式:在此模式下,只有 RTC 与 ULP 协处理器功能正常,芯片的所有其他组件都断电。在长时间间隔后传输数据的情况下,此模式非常有用。
  1. Hibernation 休眠模式:与深度睡眠模式不同,在休眠模式下,芯片会禁用内部 8 MHz 振荡器以及 ULP。RTC 恢复内存也已关闭电源,这意味着我们在休眠模式下无法保留任何数据。除了一个 RTC 计时器(在慢速时钟上)和几个 RTC GPIO 之外,其他所有内容都已关闭。它们负责将芯片从休眠模式中唤醒。这进一步降低了功耗。芯片在休眠模式下仅消耗约 2.5μA 电流。 如果你正在构建的项目不需要始终处于活动状态,则此模式特别有用。

唤醒 ESP32 的方式有 RTC(RealTimeClock) 唤醒, 因为在深度睡眠模式下,RTC Timer 仍保持运作,当 Timer 指定时间到达,即触发 CPU Restart。

还可以透过外部的 IO 脚位进行唤醒,这边的脚位并不是任意 IO,而是标记为 RTC GPIO的脚位,怎么确定那几只脚位是 RTC 的 GPIO 呢?最直觉的方法就是查阅 ESP32 的参考手册:

外部 IO 唤醒方法,可以分为 ext0 跟 ext1,两种唤醒最大的差别就在于 ext0 可以设定1个 IO 口作为唤醒源,ext1 可以同时设定多支 IO 作为唤醒机制。

硬件电路设计

使用按键电路实现开关灯的效果。

物料清单(BOM 表):

材料名称数量
1kΩ 电阻1
杜邦线(跳线)若干
面包板1

将材料按照下图相连:

软件程序设计

MicroPython 提供了 lightsleep()deepsleep() 两种低功耗模式函数:

  • lightsleep():正常低功耗模式是被唤醒后继续执行后面的语句,不带参数表示永久,带参数表示睡眠 XX ms。
  • deepsleep():深度睡眠模式唤醒后是重启,可以通过 machine.reset_cause() 复位原因函数获取复位原因,共有5 种:PWRON_RESET(电源复位)、HARD_RESET(硬重置,断电)、WDT_RESET(看门狗复位)、DEEPSLEEP_RESET(深度睡眠重启)、SOFT_RESET(软复位)。

外部唤醒 ESP32 的函数有两个 wake_on_ext0()wake_on_ext1(), 他们两个的作用都是通过外部中断把设备从睡眠模式中唤醒,但是 exti0 只能接受一个引脚,exti1 可以接受多个, level 参数表示确定高电平 / 低电平唤醒。

在 MicroPython 设备中创建文件取名 low_power.py,输入以下测试代码:

# 在 MicroPython 设备中创建文件取名 low_power.py
import machine,esp32, time
from machine import Pin


pin_13 = Pin(13, mode = Pin.IN)
#level 参数可以是: WAKEUP_ANY_HIGH 或 WAKEUP_ALL_LOW
esp32.wake_on_ext0(pin=pin_13, level=esp32.WAKEUP_ALL_LOW)


print('两秒钟后进入睡眠模式')
time.sleep(2)
print('Sleep Mode On')
# 这里不加延迟的话打印到一半就进入睡眠模式了
time.sleep_ms(100)

# 测试 Light Sleep 模式
# machine.lightsleep()    
# Light Sleep 会继续执行下面的代码
# print('解除 Light Sleep 模式')

# 测试 Deep Sleep 模式
machine.deepsleep()
# Deep Sleep 不会执行下面代码
print('解除 Deep Sleep 模式')

注意

测试本段代码需要将其保存到 Micropython 设备当中才行,在线调试时如果启用了 machine.deepsleep() 代码,无法看到 Shell 调试窗口相关的调试信息。

根据测试,我们可以看到,Light Sleep 模式被唤醒后可以继续执行后面的语句,深度睡眠模式唤醒后是重启,后面的代码不再执行。

上次编辑于:
贡献者: Luo