STM32 低功耗模式:SLEEP / STOP / STANDBY 怎么选
三种模式速览
| 模式 | 电流(典型) | CPU | SRAM | 寄存器 | 唤醒方式 | 唤醒时间 |
|---|---|---|---|---|---|---|
| SLEEP(睡眠) | ~10mA→~1mA | 停 | 保持 | 保持 | 任一中断 | 几 μs |
| STOP(停止) | ~1mA→~110μA(低功耗调压器 PWR_LOWPOWERREGULATOR_ON);主调压器约 450μA | 停 | 保持 | 保持 | EXTI / RTC | 几 μs |
| STANDBY(待机) | ~100μA→~2μA | 掉电 | 掉电 | 掉电 | RST / RTC / WAKE | 几 ms |
SLEEP 模式
CPU 停转,外设继续工作(串口能收数据、定时器继续计数)。
// 进入 SLEEP HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); // WFI = Wait For Interrupt,任一中断就会唤醒
适合:短暂空闲,比如等串口数据、等定时器。
STOP 模式
CPU 和外设都停止,SRAM 和寄存器内容保持。所有时钟停振(HSE/HSI 关了)。
// 进入 STOP HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
唤醒后需要重新配置系统时钟:
// EXTI 回调中唤醒 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { // 唤醒后先不动,main 里恢复时钟 } // main 中 HAL_PWR_EnterSTOPMode(...); // 醒来后从这里继续执行 SystemClock_Config(); // 必须重新配时钟!适合:几秒到几十秒的空闲。
STANDBY 模式
最省电。除了 RTC 和唤醒引脚,全都断电。醒来相当于复位——从 main 重新执行。
// 进入 STANDBY HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); // PA0 可唤醒 HAL_PWR_EnterSTANDBYMode();
醒来判断是否从 STANDBY 复位:
if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) { __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); printf("Woke from STANDBY\r\n"); // 注意:STANDBY 唤醒后经历复位,需重新初始化串口等外设后方可 printf }适合:电池供电、几分钟甚至几小时才工作一次的场景。
实测步骤
用万用表(mA 档)串在 VCC 回路里:
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); printf("Entering STOP in 3s...\r\n"); HAL_Delay(3000); // 进入 STOP HAL_SuspendTick(); // 暂停 SysTick(避免醒来后 HAL_Delay 出错) HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后 SystemClock_Config(); HAL_ResumeTick(); printf("Woke up!\r\n"); while (1) HAL_Delay(1000); }按下 PA0(带 EXTI),看电流从几 mA 降到几百 μA,再按一下回到几 mA。
选型指南
| 你想省电多久 | 用哪个 |
|---|---|
| 等串口数据(< 1s) | SLEEP |
| 等按键输入(几秒~几分钟) | STOP |
| 传感器定时上报(几分钟~几天) | STANDBY + RTC 唤醒 |
