单片机低功耗模式概述:睡眠、停止与待机
做嵌入式开发这些年,我越来越觉得低功耗设计不是选修课,而是必修课。你想想看,一个产品如果电池撑不过三天,功能再强用户也不会买账。而低功耗模式,说白了就是让单片机在“没事干”的时候尽量少耗电。
今天咱们先聊清楚三种最基本的低功耗模式:睡眠模式、停止模式和待机模式。这三兄弟的区别,我当年可是花了不少功夫才真正搞明白。
一、为什么需要低功耗模式?
先问个问题:单片机跑在72MHz全速工作时,电流可能到几十毫安甚至上百毫安。但大部分时间,它只是在等一个按键、等一个定时器溢出、或者等传感器数据准备好。这段时间的电流,说白了就是浪费。
低功耗模式的核心思路就一句话:关掉不需要的模块,降低时钟频率,甚至完全停止时钟。不同的关法,就对应不同的模式。
关键指标对比:
- 睡眠模式:电流约 1-10 mA(视外设而定)
- 停止模式:电流约 10-100 µA
- 待机模式:电流约 1-5 µA(甚至更低)
从毫安级到微安级,差了三个数量级。这就是你产品续航从3天变成3个月的关键。
二、三种模式的核心区别
我习惯用一个比喻来理解这三种模式:
- 睡眠模式:就像你坐在工位上打盹,有人叫你马上能醒。CPU停了,但外设还在跑。
- 停止模式:就像你回家睡觉了,闹钟响了才能醒。CPU和外设都停了,但寄存器和RAM里的数据还在。
- 待机模式:就像你出差去了另一个城市,只有紧急电话才能找到你。几乎整个芯片都断电了,醒来一切从头开始。
嗯,这个比喻虽然不精确,但能帮你快速建立直觉。下面咱们看技术细节。
| 特性 | 睡眠模式 | 停止模式 | 待机模式 |
|---|---|---|---|
| CPU时钟 | 停止 | 停止 | 停止 |
| 外设时钟 | 运行(可配置) | 停止 | 停止 |
| SRAM/寄存器内容 | 保持 | 保持 | 丢失 |
| 唤醒源 | 任意中断 | 特定外设中断(如EXTI、RTC) | 特定唤醒引脚、RTC、复位 |
| 唤醒后执行 | 从中断处继续 | 从中断处继续 | 从头执行(类似复位) |
| 典型电流 | ~5 mA | ~50 µA | ~2 µA |
我曾经踩过的坑:有一次做手持设备,我用了停止模式,以为所有外设都停了。结果发现一个GPIO没配置好,漏电导致整机电流多了200µA。后来养成习惯:进低功耗前,把所有不用的GPIO都设成模拟输入模式,或者拉高/拉低到固定电平。
三、三种模式的唤醒机制
唤醒方式决定了你该选哪种模式。我个人习惯这样选:
- 需要频繁响应外部事件(比如按键扫描、通信接收)→ 用睡眠模式。唤醒快,功耗适中。
- 需要定时唤醒做数据采集(比如每10秒读一次传感器)→ 用停止模式+RTC定时器。功耗低,还能保持数据。
- 设备大部分时间在休眠,偶尔被唤醒(比如遥控器、门磁)→ 用待机模式。功耗最低,但醒来要重新初始化。
你想想看,如果遥控器用睡眠模式,电池可能半年就没了。但用待机模式,两三年都没问题。
四、知识结构总览
下面这张图是我自己整理的,把三种模式的关系和选择逻辑画清楚了。建议你保存下来,做项目时对照着看。
五、寄存器配置初探
虽然这一章只是概述,但我还是想让你先看一眼寄存器长什么样。以STM32F1为例,进入睡眠模式只需要一条指令:
// 进入睡眠模式(WFI指令)
__WFI();
进入停止模式需要配置电源控制寄存器:
// 进入停止模式
PWR->CR |= PWR_CR_LPDS; // 低功耗深度睡眠
PWR->CR |= PWR_CR_CWUF; // 清除唤醒标志
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // 深度睡眠
__WFI();
进入待机模式就更彻底了:
// 进入待机模式
PWR->CR |= PWR_CR_PDDS; // 电源深度掉电
PWR->CR |= PWR_CR_CWUF; // 清除唤醒标志
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
我的小技巧:调试低功耗代码时,别一上来就进待机模式。先试睡眠模式,确认唤醒逻辑没问题了,再逐步切换到停止模式、待机模式。否则一旦进待机醒不来,调试器都连不上,只能重新上电——我吃过这个亏。
六、避坑指南
最后总结几个我实际项目中遇到的坑,你提前知道能省不少时间:
- GPIO浮空漏电:进低功耗前,把所有不用的GPIO设成模拟输入或固定电平。浮空引脚会通过IO保护二极管漏电。
- 唤醒源没配置好:停止模式下,不是所有中断都能唤醒。必须用EXTI、RTC等特定外设。我见过有人用UART中断唤醒停止模式,结果死活醒不来。
- 待机模式的数据保存:待机模式下SRAM内容会丢失。如果你需要保存数据,要么用RTC备份寄存器,要么在进待机前把数据写到Flash里。
- 调试器连接问题:进待机模式后,调试接口也会断电。所以调试时建议先用睡眠模式验证逻辑,最后再切到待机模式。