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 真正厉害的地方。