4、电源管理基础:U5的多种工作模式(Run/Sleep/Stop/Standby)

做低功耗嵌入式设计,说白了就是跟电池容量较劲。你想想看,一块纽扣电池要撑几年,MCU 不可能一直全速跑。STM32U5 在这方面做得挺绝——它提供了好几种工作模式,从跑得飞快的 Run 模式,到几乎断电的 Standby 模式,中间还有 Sleep 和 Stop。每种模式都有自己的脾气,用对了省电,用错了可能连数据都保不住。

我个人习惯,拿到一个新板子,第一件事就是把所有模式都跑一遍,看看电流到底是多少。嗯,咱们今天就一个一个过。

4.1 Run 模式:全速前进

Run 模式就是 MCU 的「满血状态」。CPU 核心全速运行,所有外设都能用,Flash 和 SRAM 也都供电。这时候功耗最高,但性能也最强。

U5 在 Run 模式下,可以跑到 160MHz。我建议你根据实际需求来调频率,别一上来就拉满。我在项目中遇到过,一个传感器采集任务其实 16MHz 就够用了,结果同事直接开了 160MHz,功耗多了好几倍,电池寿命直接砍半。

这里有个关键点:U5 的 Run 模式其实还分两种——Range 1 和 Range 2。Range 1 是高性能模式,电压高,频率能到 160MHz;Range 2 是低性能模式,电压低,频率最高只能到 100MHz。说白了,Range 2 就是拿性能换功耗。

重要提示:切换 Range 时,需要先降低频率,再切换电压范围。顺序搞反了,系统可能会直接挂掉。我曾经在调试时吃过这个亏,代码里忘了降频,结果一切换就 HardFault,查了半天才发现。

4.2 Sleep 模式:浅度睡眠

Sleep 模式,说白了就是 CPU 核停了,但外设还在跑。这时候 CPU 不再取指执行,但 SRAM 和寄存器内容都保留着。一旦有中断来了,CPU 能立刻醒来继续干活。

U5 的 Sleep 模式有两种:

  • Sleep-on-exit:中断处理完后自动睡回去。适合轮询加中断的场景。
  • 普通 Sleep:需要手动调用 WFI 或 WFE 指令进入,醒来后继续执行后面的代码。

我个人习惯用 Sleep-on-exit 做 RTOS 的空闲任务。你想想看,系统没事干的时候就睡,有中断就醒,处理完再睡,这样既省电又不用改太多代码。

Sleep 模式的电流大概在几百微安到几毫安之间,具体看你开了哪些外设。我建议你关掉不用的外设时钟,别让它们白白耗电。

小技巧:进入 Sleep 前,把 GPIO 配置成模拟模式或上拉/下拉固定电平,能省不少电。浮空的 GPIO 会漏电,这个坑我踩过。

4.3 Stop 模式:深度睡眠

Stop 模式就厉害了。CPU 停了,大部分外设也停了,但 SRAM 和寄存器内容还在。U5 的 Stop 模式又细分成 Stop0、Stop1 和 Stop2,唤醒时间从快到慢,功耗从高到低。

模式 唤醒时间 典型电流 保留内容
Stop0 几微秒 几十微安 全部 SRAM 和寄存器
Stop1 十几微秒 十几微安 全部 SRAM 和寄存器
Stop2 几十微秒 几微安 部分 SRAM 和寄存器

为什么会有三种?因为不同的应用对唤醒速度和功耗要求不一样。比如蓝牙信标,几秒钟发一次广播,用 Stop2 最合适,电流低到几微安。但如果是需要快速响应的传感器节点,可能就得用 Stop0 了。

我记得有一次做智能门锁项目,客户要求电池用两年。我们一开始用的 Stop0,电流 30 微安,算下来只能撑一年半。后来换成 Stop2,电流降到 5 微安,电池寿命直接翻倍。代价是唤醒慢了 50 微秒,但门锁开锁本来就要几百毫秒,这点延迟根本感觉不到。

注意:Stop2 模式下,只有 64KB 的 SRAM2 能保留数据,SRAM1 和 SRAM3 都会掉电。如果你有大量数据要保存,得提前搬到 SRAM2 里。我曾经有个同事没注意这个,醒来后发现数据全丢了,排查了一整天。

4.4 Standby 模式:几乎关机

Standby 模式,说白了就是除了备份域,其他全断电。CPU、SRAM、大部分外设都关了,只有 RTC、备份寄存器和几个唤醒引脚还活着。这时候电流能降到几十纳安,是真正的「超低功耗」。

进入 Standby 后,系统相当于重启。醒来时,代码会从 Reset_Handler 开始执行,就像按了复位键一样。所以你要在启动代码里判断一下:是上电复位,还是从 Standby 唤醒?

if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) {
    // 从 Standby 唤醒
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    // 恢复现场
} else {
    // 正常上电
    // 初始化所有外设
}

这个判断很重要。我见过有人没做这个区分,每次从 Standby 醒来都重新初始化所有外设,结果之前保存的配置全丢了,设备直接跑飞。

Standby 模式适合那种「大部分时间都在睡觉,偶尔起来干点活」的场景。比如温湿度传感器,每 10 分钟采集一次数据,中间 9 分 59 秒都在 Standby 里待着。这样一颗 CR2032 纽扣电池能撑好几年。

4.5 模式切换实战建议

说了这么多,到底怎么选?我总结了几条经验:

  • 需要实时响应(比如电机控制):用 Run 模式,别睡。
  • 偶尔空闲(比如等待按键):用 Sleep 模式,醒来快。
  • 周期性工作(比如传感器采集):用 Stop 模式,根据唤醒速度选 Stop0/1/2。
  • 超长待机(比如电池供电的 IoT 设备):用 Standby 模式,配合 RTC 唤醒。

另外,我建议你在切换模式前,先把不用的外设时钟关了,GPIO 配置好,电源稳压器也调到合适的模式。U5 的电源管理挺灵活的,但灵活也意味着容易出错。嗯,多测几次电流,心里就有数了。

调试小技巧:用 U5 的 LPUART 可以在低功耗模式下接收数据。我在调试时经常用这个功能,在 Stop 模式下还能打印日志,省了不少事。

好了,电源管理的基础就这些。下一章咱们聊聊 TrustZone 怎么跟这些低功耗模式配合,那才是 U5 真正厉害的地方。