3、深度睡眠模式:深度睡眠与睡眠的区别、稳压器配置、内存保持策略
好,咱们接着聊深度睡眠。说实话,很多工程师把睡眠和深度睡眠混为一谈,觉得不就是睡得更沉一点嘛。其实差别大了去了。我在一个电池供电的传感器项目里就吃过这个亏——明明进了睡眠,功耗还是降不下来,后来一查,核心压根没进深度睡眠模式。
3.1 深度睡眠 vs 睡眠:到底差在哪?
先看一张对比表,你一眼就能明白区别在哪。
| 特性 | 睡眠模式 (Sleep) | 深度睡眠模式 (Deep Sleep) |
|---|---|---|
| CPU 时钟 | 停止 | 停止 |
| 系统时钟 (SYSCLK) | 运行 | 停止或降频 |
| 稳压器 (Regulator) | 正常模式 (Range 1) | 低功耗模式 (Range 2 / 低电压) |
| 唤醒延迟 | 几微秒 | 几十到几百微秒 |
| 典型电流 (STM32L4) | ~100 µA/MHz | ~1 µA 左右 |
| RAM 保持 | 全部保持 | 可配置保持区域 |
看到没?核心差异在稳压器和系统时钟。睡眠模式只是停了 CPU 的时钟,但稳压器还在满负荷工作,系统时钟(比如 HSI、HSE)也还在跑。深度睡眠则把系统时钟也停了,稳压器切到低功耗档位,这才是真正的“省电模式”。
关键指标:深度睡眠的电流通常是睡眠模式的 1/100 甚至更低。如果你的产品要求待机电流在 10 µA 以下,睡眠模式基本没戏,必须上深度睡眠。
3.2 稳压器配置:Range 1 vs Range 2
稳压器配置是深度睡眠里最容易踩坑的地方。我刚开始做低功耗驱动时,以为只要调个寄存器就行,结果发现唤醒后外设工作不正常——因为电压不够。
Cortex-M 内核(比如 STM32L 系列)的稳压器通常有多个工作范围:
- Range 1 (正常模式):输出电压 ~1.2V,支持最高主频,功耗高。
- Range 2 (低功耗模式):输出电压 ~1.0V,主频受限(通常 ≤ 2 MHz),功耗低。
进入深度睡眠时,你需要手动把稳压器从 Range 1 切到 Range 2。怎么切?看代码:
/* 进入深度睡眠前的稳压器配置示例 (STM32L4) */
void enter_deep_sleep(void) {
// 1. 设置稳压器为低功耗模式 (Range 2)
HAL_PWREx_EnableLowPowerRunMode(); // 或者直接操作 PWR_CR1 寄存器
// 2. 选择深度睡眠模式
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
// 注意:这里用 PWR_MAINREGULATOR_ON 表示进入睡眠,但实际深度睡眠需要配合 PWR_CR1 的 LPDS 位
// 更直接的做法:
// PWR->CR1 |= PWR_CR1_LPDS; // 低功耗深度睡眠
// SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // 设置 SLEEPDEEP 位
// __WFI();
}
注意:唤醒后,稳压器不会自动切回 Range 1。你必须在唤醒中断服务程序里手动恢复 Range 1,否则外设(比如 ADC、DMA)可能因为电压不足而工作异常。我曾经在量产前才发现这个问题,差点改 PCB。
3.3 内存保持策略:哪些 RAM 能丢?
深度睡眠下,RAM 不是全部保持的。以 STM32L4 为例,SRAM 分为多个区域:
- SRAM1 (96 KB):默认保持,但可以关闭。
- SRAM2 (32 KB):默认保持,也可以单独关闭。
- 备份 SRAM (4 KB):始终保持(由 VBAT 供电)。
你想想看,如果你的应用只需要保存几个关键变量(比如计数值、状态标志),完全没必要让整个 SRAM 都保持供电。关掉不必要的 RAM 区域,能再省 50% 的深度睡眠电流。
配置方法:
/* 关闭 SRAM2 以降低深度睡眠功耗 (STM32L4) */
void config_ram_retention(void) {
// 关闭 SRAM2 的保持
PWR->CR2 |= PWR_CR2_SRAM2STOP;
// 或者更细粒度:只保留 SRAM1 的低 32 KB
// 通过 PWR->CR1 的 RRL 位域配置
}
我的习惯:在进入深度睡眠前,把需要保留的数据(比如 RTC 闹钟值、传感器校准参数)拷贝到备份 SRAM 里,然后关掉所有主 SRAM。这样深度睡眠电流可以降到 0.5 µA 以下。
3.4 深度睡眠的完整流程
下面这张 SVG 图总结了深度睡眠的完整状态机,你对照着看会更清楚。
流程其实不复杂:运行 → 准备(稳压器 + RAM)→ 执行 WFI/WFE → 深度睡眠 → 唤醒后恢复。但每一步都有细节,尤其是唤醒后的恢复,很多人会忘。
3.5 避坑指南:我踩过的三个坑
- 唤醒后外设死掉:稳压器没切回 Range 1。解决办法是在唤醒 ISR 里第一件事就是恢复稳压器。
- RAM 数据丢失:关掉了不该关的 SRAM 区域。我建议你在调试阶段先全部保持,确认哪些变量必须保留后,再逐步关闭。
- 唤醒延迟比预期长:深度睡眠的唤醒延迟主要来自稳压器从 Range 2 恢复到 Range 1 的时间。如果你的应用对唤醒时间敏感(比如响应按键),可以考虑用睡眠模式代替。
总结一下:深度睡眠的核心就是“稳压器降档 + 系统时钟停 + RAM 按需保持”。配置时记住三步:切稳压器、配 RAM、设 SLEEPDEEP 位。唤醒后别忘了恢复。做到这几点,你的待机电流就能从毫安级降到微安级。