去年冬天,一批装在冷库里的无线温湿度采集器陆续返修。规格书上白纸黑字写着"续航一年",现场实测不到十天就集体趴窝。拆开固件看了一圈,这根本不是电池的问题,是低功耗策略从设计第一天就跑偏了——团队把"省电"理解成"把 MCU 塞进睡眠模式",而真正吃掉电量的,是那些没人正眼看过的周边电路。这件事之后我养成了一个习惯:任何电池供电的项目,先做功耗预算,再写第一行代码。
这篇文章想聊的就是这件事:低功耗策略能带来什么,又会让你付出什么代价,以及怎么在两者之间找那个不难受的平衡点。不管你是做可穿戴、无线传感器、便携仪表,还是做那种"三年换一次电池"的工业节点,这套思路都能直接拿去用。我会把预算怎么算、睡眠档位怎么选、哪些坑是半年后才暴露的、测量怎么测才准,一条条拆开讲。
1. 一笔容易被算错的账:低功耗换来的到底是什么
1.1 把"续航一年"翻译成平均电流
很多人做低功耗设计的第一步就错了:盯着峰值电流看。示波器上抓到一个 25mA 的发射尖峰,就下结论"太费电了",然后拼命去砍这个尖峰。但电池不看你跑得多快,它只认平均电流。
换算关系简单到不需要推导:容量除以时间。
一颗 CR2032 标称容量 220mAh,如果目标是续航一年:
平均电流 = 220 mAh / (365 × 24 h) = 220 / 8760 ≈ 0.0251 mA ≈ 25 µA也就是说,你这块板子上所有东西加起来,长期平均电流必须压到 25µA 以内。注意是平均,不是待机。任何一段时间的超标都会从总账里扣。
占空比模型是算平均电流的主力工具:
平均电流 = Σ (各工作状态电流 × 该状态时间占比)比如无线模块发射时 25mA,每次持续 120ms,每 15 分钟发一次:
25 mA × 120 ms / 900 s = 25 × 0.12 / 900 ≈ 3.33 µA看起来挺省。但如果发射周期是 60 秒,同样的动作就变成 50µA——单独一项就把 25µA 的预算撑爆两倍。所以低功耗设计里最有效的杠杆从来不是"把发射电流从 25mA 降到 20mA",而是"把发射频率从 1 分钟一次改成 15 分钟一次"。前者省 20%,后者省 93%。
这也是为什么我总劝人先画功耗表,再动烙铁。
1.2 收益不止续航:热量、体积、成本的三重回报
把平均电流压下来的好处,续航只是明面上那个。真正让我坚持做低功耗的,是另外三件事。
第一是热。密闭塑料壳里塞一个 100mA 常开的模组,壳内温升能有十几度。温升一上来,所有传感器的精度指标都要打折,电池自身的老化速度也会加快。低功耗方案顺带把这个问题解决了——平均电流降两个数量级,热设计基本不用做了。
第二是体积和成本。当平均电流从毫安级降到几十微安,电池选型的选择面一下就宽了。你不再需要 18650 或者软包锂电,一颗 CR2032、一枚 CR2450,甚至两颗纽扣并联就够用。省下来的不光是电池钱,还有结构空间、充电管理电路、充电接口、以及跟充电相关的安规认证成本。我经手过一个项目,光是把锂电换成纽扣电池这一项,BOM 成本降了 18%,结构件少了两个。
第三是可靠性。这一点常被忽略。电池放电电流越小,内阻上的压降越小,实际能用的放电深度越深。同样一颗电池,100mA 放电可能只放出 60% 的容量就触到截止电压,而 20µA 放电能放出 90% 以上。所以低功耗策略某种程度上是在"凭空"增加电池容量。
1.3 代价清单:延迟、精度、可靠性、可调试性
现在说不好听的。省电这件事没有免费午餐,你省下来的每一微安,都从别的地方扣走了。我把它整理成一张表,方便对照自己项目里能不能接受:
| 代价类型 | 具体表现 | 典型严重程度 |
|---|---|---|
| 响应延迟 | 设备在深睡,主机指令要等唤醒周期才被处理 | 高,直接影响用户感知 |
| 时钟精度 | 用内部 RC 替代晶振,走时误差从 ppm 级掉到百分比级 | 高,业务窗口错位 |
| 数据完整性 | 深睡期间 RAM 丢失,掉电瞬间写入损坏 | 高,可能丢关键数据 |
| 可调试性 | 调试器一连上就进不去低功耗模式,问题复现不了 | 中,但极其折磨人 |
| 状态机复杂度 | 唤醒后外设要重新初始化,状态恢复逻辑容易漏 | 中高,长期隐患 |
| 认证与协议约束 | 通信间隔不能无限拉长,有下限 | 中,设计早期就要确认 |
这张表里的每一项我都踩过。最典型的是"响应延迟":我们把一个 BLE 设备的连接间隔从 100ms 放宽到 2s,电池寿命从 3 个月变成 14 个月,但用户点开 App 要愣等两秒才看到数据,投诉量翻倍。最后折中到 500ms,续航落在 8 个月左右,才算各方都能接受。
这就是低功耗的本质:它是一个多目标优化问题,不是单目标的最省电竞赛。
2. 功耗预算怎么算才不翻车
2.1 从能量守恒出发搭一张能用的功耗表
功耗表不是写给自己看的文档,是后面所有决策的依据。我的做法是把它做成一个可计算的表格,每一行一个耗电单元,列三样东西:工作电流、占空比、平均电流贡献。
以一块无线温湿度节点为例,下面是"初版设计"的实测数据:
| 耗电单元 | 工作电流 | 占空比 | 平均电流贡献 |
|---|---|---|---|
| MCU(Sleep 模式) | 500 µA | 100% | 500 µA |
| RTC + 内部 RC 时钟 | 1 µA | 100% | 1 µA |
| 传感器(常开待机) | 120 µA | 100% | 120 µA |
| 传感器 I2C 上拉(10k) | 330 µA | 100% | 330 µA |
| 电源芯片静态电流 | 150 µA | 100% | 150 µA |
| 采集与运算 | 8 mA | 40 ms / 60 s | 5.3 µA |
| 无线发射 | 25 mA | 120 ms / 60 s | 50 µA |
| 状态指示灯 | 2 mA | 20 ms / 5 s | 8 µA |
| 合计 | ≈ 1.16 mA |
220mAh 除以 1.16mA,190 小时,不到 8 天。跟现场返修那批设备的表现完全对得上。
然后是优化后的版本:
| 耗电单元 | 工作电流 | 占空比 | 平均电流贡献 |
|---|---|---|---|
| MCU(Stop2,仅 RTC 域供电) | 1.5 µA | 100% | 1.5 µA |
| RTC + 外部 32.768kHz 晶振 | 0.8 µA | 100% | 0.8 µA |
| 传感器(深度关断) | 0.1 µA | 100% | 0.1 µA |
| 传感器 I2C 上拉(1M,仅通信时使能) | 3.3 µA | 5% | 0.17 µA |
| 电源芯片静态电流(低 Iq LDO) | 4 µA | 100% | 4 µA |
| 采集与运算 | 8 mA | 40 ms / 300 s | 1.07 µA |
| 无线发射 | 25 mA | 120 ms / 900 s | 3.33 µA |
| 无线接收窗口 | 6 mA | 60 ms / 900 s | 0.4 µA |
| 状态指示灯(已取消) | 0 | 0 | 0 |
| 合计 | ≈ 11.4 µA |
220mAh / 11.4µA ≈ 19300 小时 ≈2.2 年。再考虑纽扣电池在高脉冲下的容量损失打个七折,实际落在 1.5 年左右,目标达成。
从 1.16mA 到 11.4µA,整整两个数量级。值得注意的是,其中没有任何一项是靠"把 MCU 睡眠调得更深"实现的,最大的两块收益来自砍掉上拉电阻的持续耗电(330µA→0.17µA)和换掉高静态电流的电源芯片(150µA→4µA)。
2.2 五个最容易被忽略的漏电大户
上面那个例子里的前四名,我在不同项目里反复遇到。单独说一下。
第一个是 GPIO 悬空。这是最隐蔽的。未使用的引脚如果配成浮空输入,输入级的施密特触发器可能停在阈值附近来回翻转,某些工艺下这一根引脚就能贡献几十微安甚至上百微安。我见过一个板子,八根悬空 IO 加起来吃掉 200µA。处理办法很土但有效:所有未使用的引脚,要么配成模拟输入,要么配成推挽输出并驱动到低电平。
第二个是上拉电阻。计算很简单:3.3V 通过 10kΩ 到地是 330µA。这个数字很多人第一次看到会愣一下——一根电阻等于一整块板子的预算。所以常开的上拉宁可放到 100kΩ 甚至 1MΩ(前提是速率跟得上),或者干脆用 MOS 管门控,只在通信的那几十毫秒里接通。
提示:I2C 上拉的选型要看总线电容和速率。100kHz 下 100kΩ 上拉配 200pF 总线电容,上升时间约 22µs,勉强够用;但 400kHz 就不行了。省电和信号完整性在这里是要打架的,别只算电流。
第三个是电源芯片。线性稳压器的静态电流(Quiescent Current)差异巨大。有些老型号的静态电流在毫安级,你后面再怎么省都是白搭。选型时把 Iq 当成第一指标看,几十微安和几微安的差距,放在年度预算里就是能不能达标的分界线。另外开关电源在轻载下的效率会塌,如果大部分时间都在微安级,用 LDO 反而比 DC-DC 更合适——这个反直觉的结论我验证过不止一次。
第四个是电池电压检测的分压网络。想监测电量,很多人顺手挂一对 100k/100k 分压电阻到 ADC。这就是 16.5µA 的常年开销。正确做法是用一颗小 MOS 在采样瞬间接通分压网络,采完立刻断开,占空比做到 0.1% 以下,平均贡献就降到纳安级。
第五个是调试口和复位电路。调试器连着的时候,很多 MCU 会因为调试时钟域保持运行而进不去最低功耗模式。这不是 bug,是设计使然。所以功耗测试必须在断开调试器的状态下做,烧完固件拔线、重新上电,再测。这个细节听起来废话,但我见过太多人对着连着 J-Link 的板子调了一整天睡眠模式。
2.3 纽扣电池的隐藏限制:内阻、脉冲能力与温度降额
算完平均电流别急着庆祝,还得过电池这一关。纽扣电池有两个特性经常被忽略。
内阻。CR2032 的内阻在几十欧姆量级,而且随放电和低温显著上升。当你的无线模块瞬间抽 25mA,电池内阻上的压降可能达到几百毫伏,电压瞬间跌破 MCU 的欠压复位阈值,直接重启。表现出来就是"电池还有电,但设备一直重启"。
解决办法是在电池和负载之间并联一颗 47µF~100µF 的陶瓷或钽电容,让它来扛脉冲。电阻分压算一下:假设内阻 40Ω,脉冲电流 25mA,压降 1V——如果不加电容,3V 的电池瞬间只剩 2V。加一颗 100µF 电容后,脉冲持续时间 120ms 里电容能补上大部分电荷,电池端看到的电流就被摊平了。
温度降额。纽扣电池在低温下容量衰减很明显。0℃ 时可能还剩 90%,-20℃ 时可能只剩一半,-40℃ 基本就不能用了。如果你的设备要装在冷库、户外机箱、冷链运输场景里,电池选型必须按最低工作温度来算,而不是按室温标称值。我一般会在预算里留 40% 的余量。
注意:低温下电池内阻还会升高,脉冲压降问题会更严重。冷启动场景里,电容容值建议再放大一倍。
3. 睡眠档位越深,唤醒的账越贵
3.1 各档睡眠模式的真实取舍
各家 MCU 的低功耗模式名字不一样,但本质上都是同一套光谱:从"只关时钟"到"只留备份域",功耗越来越低,代价越来越大。下面这张表是通用映射,具体数值请以你手上那颗芯片的数据手册为准:
| 档位 | 保留内容 | 典型电流量级 | 唤醒时间 | 唤醒后要做什么 |
|---|---|---|---|---|
| Run | 全部 | mA ~ 数十 mA | - | - |
| Sleep | 内核停,外设时钟可保留 | 数百 µA | 数个时钟周期 | 基本不用恢复 |
| Stop / Deep Sleep | 时钟全停,RAM 保留 | 1 ~ 10 µA | 数 µs ~ 数十 µs | 重配时钟、重启外设 |
| Standby | 仅备份域 + RTC | 0.5 ~ 3 µA | 数十 µs ~ ms | 从复位向量启动,RAM 丢失 |
| Shutdown / Off | 几乎全关 | < 0.5 µA | ms 级 | 完整冷启动,需外部事件唤醒 |
关键认知:功耗和唤醒代价不是线性的。从 Run 到 Sleep 省了 90% 的电,唤醒几乎没代价;从 Stop 到 Standby 又省了 50% 的电,但唤醒后你得从复位向量重新跑一遍启动代码,Flash 读取、时钟校准、外设初始化加起来可能有几毫秒。这几毫秒乘以唤醒频率,就是一笔要算清楚的账。
3.2 唤醒路径上的时间成本与能量成本
我习惯把每次唤醒的总能量算出来:
单次唤醒能量 ≈ 唤醒期间平均电流 × 唤醒持续时间 唤醒持续 = 时钟稳定时间 + 外设初始化 + 实际业务处理时间拿 Standby 举例。假设每次唤醒需要:
- 高速时钟起振并稳定:1.5 ms
- 外设初始化(UART、SPI、ADC 校准):1 ms
- 业务处理:0.5 ms
- 平均电流:6 mA
总时长 3ms,那么单次唤醒消耗6mA × 3ms = 18 µAh,折合成平均电流,如果你每 10 秒唤醒一次,就是6mA × 3ms / 10s = 1.8µA,还挺划算。但如果业务需要每秒唤醒,就是 18µA,直接把预算吃光。
所以判断标准很清晰:唤醒频率低(分钟级以上),就往深睡走;唤醒频率高(秒级以下),Stop 模式往往比 Standby 更划算。这不是感觉,是能算出来的。
还有一个容易漏的点:传感器和外部芯片的恢复时间。传感器从关断到输出稳定数据,可能需要几十毫秒。如果它比你 MCU 的唤醒时间还长,那整个唤醒周期的时间就由它决定,MCU 深度睡眠省下的那点时间全被它吃回去了。
3.3 时钟源:精度、启动时间与功耗的三角关系
低功耗设计里最纠结的选型,大概就是 RTC 时钟源。三种选择,各有一个短板:
| 时钟源 | 典型精度 | 启动时间 | 功耗 | 适用场景 |
|---|---|---|---|---|
| 内部 RC(LSI) | ±1% ~ ±5% | 极快(µs 级) | 最低 | 对时间精度无要求的短周期唤醒 |
| 外部晶振(LSE) | ±20 ppm(含温漂约 ±50 ppm) | 0.5 ~ 2 s | 约 0.5 ~ 1 µA | 需要长时间守时、定时通信 |
| 外部晶振 + 温度补偿 | ±5 ppm 以内 | 同上 | 高(数 µA ~ 数十 µA) | 需要精准授时或长期免校准 |
内部 RC 的问题是精度。±2% 看起来不大,换算一年:8760h × 2% = 175 小时 ≈ 7.3 天。也就是说一年下来你的设备时钟能跑偏一个星期。如果业务里有"每天固定时间上报"这种需求,一个月后上报时间就漂到半夜去了。
外部晶振的问题不是精度,是启动时间。32.768kHz 晶振的起振时间在几百毫秒到两秒之间,起振期间功耗比稳态高得多。如果你为了省那 0.5µA 的稳态电流,每次唤醒都关掉晶振、下次再重新起振,那反而亏了——起振一次的能耗可能比它连续跑一小时还多。
我的经验结论是:只要 RTC 需要长期守时,LSE 就让它一直跑着,那 0.5µA 花得值。反过来,如果只是需要一个周期性的定时唤醒、对绝对时间没概念,用内部 RC 完全够,前提是你接受它每次唤醒间隔有百分之几的抖动。
4. 那些半年后才暴露的风险
4.1 时间漂移怎么变成业务故障
ppm 这个单位很会骗人,因为它看起来太小了。我们把它换算成能感知的量:
| 精度 | 每天误差 | 每月误差 | 每年误差 |
|---|---|---|---|
| ±1 ppm | 0.086 s | 2.6 s | 31 s |
| ±20 ppm | 1.7 s | 52 s | 10.5 min |
| ±50 ppm | 4.3 s | 2.2 min | 26 min |
| ±2%(RC) | 28.8 min | 14.4 h | 7.3 天 |
看清楚了吗?一颗普通的 ±20ppm 晶振,一年漂 10 分钟,大部分场景无所谓。但如果你用的是内部 RC,一年漂一星期,那所有跟"绝对时间"相关的业务逻辑都会出问题。
具体的故障形态我见过几种。一是定时上报窗口错位:网关只在每小时的第 0~5 分钟开接收窗口,设备时钟漂了之后对不上,数据全丢。二是数据时间戳不可信:采集数据带的时间戳跟真实时间差了几小时,后端做趋势分析全是错的。三是安全握手失败:某些通信协议在建立连接时会校验时间偏差,漂太多直接握手不上,设备表现为"连不上网"。
对策分三层。最省事的是定期时间同步:设备每隔一段时间从网关或上位机同步一次时间,前提是通信链路可用。第二层是温补或者晶振筛选:把晶振按实测频率偏差分档,把偏差小的用在最苛刻的产品上,成本几乎不增加,只需要产线多一道测试工位。第三层是软件补偿:在标定时测出每块板的实际频偏,把补偿系数写进非易失存储,固件在计时时用这个系数修正。这个方法最省钱,效果也不错,缺点是需要逐板标定,产线工时增加。
4.2 掉电写入与存储器寿命
深睡模式下,MCU 掉电的瞬间正在写 Flash,会留下一块半新半旧的数据。更麻烦的是寿命。片内 Flash 的擦写寿命通常在 1 万到 10 万次之间,而且擦除是按扇区来的,不是按字节。
算一笔账:如果设备每 60 秒存一条记录,一年就是 52.5 万次写入。哪怕你做的是整扇区擦除、一条扇区塞 100 条记录,一年也要 5250 次擦除。如果扇区寿命是 1 万次,这块板子两年就写穿了一个扇区。
我在项目里的做法是三个层次:
第一,能不写就不写。数据先在 RAM 里攒着,攒够一批再落盘。掉电会丢数据,但可以用一颗小电容或者超级电容撑住最后几毫秒,把 RAM 里的数据紧急刷下去。这个方案的成本是几毛钱,收益是把写入次数降低一到两个数量级。
第二,写之前先看电压。深睡设备在电池快耗尽时电压会掉,如果这时还在写 Flash,很可能写到一半掉电复位。我一般在固件里设一条硬阈值:电池电压低于某个值就停止所有非必要的写入操作,只保留最关键的运行状态。
第三,双备份加校验。关键配置存两份,每份带 CRC。读取时先校验主份,坏了就回退到备份。写入时先写备份、校验通过、再写主份。这样任何时刻掉电,至少有一份是完整的。代价是占用双倍空间和双倍写入次数,所以只用在真正关键的数据上。
4.3 状态丢失与看门狗兜底
Standby 模式下 RAM 不保留,只有备份寄存器和 RTC 域还活着。这意味着唤醒后你有两件事必须做对:
一是把关键状态存进备份寄存器。比如"已连接的对端地址""上次成功上报的序号""累计计数",这些如果放在普通 RAM 里,每次唤醒都会归零。归零带来的后果可能是重复上报、重复计费、序号回绕。
二是看门狗的低功耗行为要确认清楚。独立看门狗在 Stop 模式下通常还在跑,而且很多芯片的看门狗时钟是独立的低速时钟,无法关闭。如果你进了深睡但没安排喂狗,几秒后就会被复位,而复位之后的状态恢复逻辑如果写得不好,设备可能陷入"睡→复位→睡→复位"的循环,看起来像是在工作,实际上什么都没干,电池还一直在被消耗。
提示:调试低功耗阶段,我会把看门狗先关掉,把唤醒逻辑跑通,最后再把看门狗加回来,单独验证一遍它在各个睡眠档位下的行为。这两个阶段混在一起调,会浪费掉大量时间。
5. 通信层的省电陷阱
5.1 心跳周期与重连风暴
无线通信是低功耗设计里最矛盾的部分。连接保持得越紧,断连检测越快,但心跳功耗越高;心跳放得越松,功耗越低,但一旦断连你可能要很久才知道。
更要命的是重连的代价远高于保持连接。一次完整的重连包含扫描、广播、协商、鉴权、密钥交换,能耗可能是维持一个连接若干秒的几十倍。我实测过一个 BLE 设备:维持连接的平均电流约 200µA,而一次断连重连过程的瞬时电流能到十几毫安,持续一到两秒。
所以策略不能是"无脑拉长心跳"。正确做法是分层:心跳周期放长,但断连检测交给更便宜的手段。比如约定"连续 N 个心跳周期收不到对方回应才判定断连",而不是"每个心跳周期都要求对方立刻回应"。同时给重连加退避和抖动:失败后不是立刻重试,而是按 1s、2s、4s、8s 的指数退避重试,并且叠加一个随机抖动。
不加抖动的后果是重连风暴:网关重启,几百个设备在同一秒同时发现断连、同时发起重连,信道瞬间拥塞,谁都连不上,然后所有人一起退避、一起重试,形成周期性的雪崩。加一个 0~30 秒的随机抖动,这个问题就基本消失了。
5.2 发射功率、重传与总能耗的悖论
有个反直觉的结论:降低发射功率不一定省电。
发射功率降一半,单次发射的电流可能从 25mA 降到 15mA。但如果这导致丢包率从 1% 上升到 20%,你就得靠重传补偿,平均要发 1.25 次才成功。算下来:
高功率:25 mA × 1.01 次 = 25.25 mA 等效 低功率:15 mA × 1.25 次 = 18.75 mA 等效这个例子里低功率还是赢了,但优势只剩 25%,而不是表面上的 40%。如果丢包率再高一点,比如 50%,低功率就彻底输了:15 × 2 = 30mA,比高功率还费。
所以发射功率的优化目标不是"最低",而是总能耗最低点。这个点通常出现在接收端灵敏度附近,需要实测丢包率曲线才能找到。做法很简单:在实验室里固定距离(比如覆盖范围的边缘),把发射功率从最高往下调,每档测 200 次通信的成功率和平均重传次数,算出每档的等效能耗,选最低的那个。
另外,接收往往比发射更费电,因为接收窗口是被动等着的,你不知道数据什么时候来,只能一直开着。这一点在星型网络里尤其明显。降低接收能耗的办法是让设备少开接收窗口,或者把接收窗口对齐到网关的发送时刻——这就引出下一个问题。
5.3 把通信窗口对齐到设备时钟
设备不知道网关什么时候发数据,网关也猜不到设备什么时候醒。如果两边各睡各的,就只能是设备频繁开窗去碰运气,或者网关反复重发。
解决办法是时间对齐。设备根据自己维护的时钟,计算出下一个通信窗口的绝对时刻,双方都按这个时刻来。设备在窗口开启前几十毫秒醒来、开接收、收完立刻睡。窗口可以开得很短(比如 100ms),功耗就低。
但这套方案的命门是时钟精度——前面算过,RC 时钟一年漂一星期,窗口根本对不上。所以对齐方案必须配一颗像样的晶振,并且做定期校准。窗口宽度也要留余量:如果双方时钟误差合计是 ±100ms,窗口至少开 250ms 才稳妥。
还有一个细节:窗口要对齐到晶振的整周期边界。这不是玄学,是因为校准后残余误差在短时间内是近似线性的,对齐到固定的绝对时刻能让误差不累积。我在一个抄表项目里把这个细节做好之后,窗口宽度从 500ms 压到 200ms,单台设备的平均电流降了大约 3µA,一年下来就是一块电池的差距。
6. 怎么测、怎么回归、怎么量产
6.1 测量工具与"测不准"的坑
测低功耗电流,万用表基本没法用。原因有三:一是量程切换慢,抓不到毫秒级的脉冲;二是采样率低,一个 20mA/10ms 的尖峰在万用表上可能只看到一个平均值;三是分流电阻的压降(burden voltage)会改变被测电路的工作状态——你用 1Ω 分流电阻测 200mA 的脉冲,压降就是 200mV,足够让一颗低电压的 MCU 复位。
我常用的工具组合是这样:
| 工具 | 能测什么 | 局限 |
|---|---|---|
| 台式万用表 | 静态 µA 级电流 | 抓不到瞬态,压降大 |
| 示波器 + 电流探头 | 瞬态波形 | 小电流档噪声大 |
| 专用功耗分析仪 | 从 nA 到 mA 全量程切换 | 价格高 |
| 便携功耗分析仪 | 无线设备的长期记录 | 带宽有限,快速脉冲会失真 |
如果预算有限,我的折中方案是两段式测量:用前端带自动量程切换的电流放大器配示波器,测瞬态波形;用台表测长时间静置的平均电流。两者交叉验证,基本能覆盖所有场景。
测量过程中有几个坑必须注意。第一,断开调试器。前面说过,但值得再说一遍。第二,确认所有外部连线。连着的 USB 线、串口线、仿真器都可能通过保护二极管给板子偷偷供电,你测到的"待机 3µA"可能是假象。第三,测之前让设备进入稳定状态。有些设备在上电头几分钟会有校准、组网、日志写入等动作,直接测平均值会失真。第四,注意温度。半导体漏电随温度指数上升,同样一块板子,25℃ 和 60℃ 的静态电流可能差好几倍。产品要在高温环境用的话,功耗测试必须在高温箱里做一遍。
6.2 建立功耗回归基线
低功耗最怕的不是一开始没做好,而是做好的东西被后来的改动吃掉了。加了一个日志打印、改了一个上拉电阻、换了一版驱动,静态电流从 3µA 变成 300µA,而没人发现。
我的做法是把功耗测试变成固件发布流程里的一个固定环节。每次出固件,都在同一块基准板、同样的温度、同样的负载条件下跑一遍标准场景(静置 10 分钟 + 完整业务循环 3 次),记录几个关键数字:
- 静置平均电流(µA)
- 单次业务周期总电荷(µAh)
- 单次唤醒最大瞬时电流(mA)
- 唤醒持续时间(ms)
把这四个数记到一张表里,跟历史版本对比。任何一个指标恶化超过 15%,就当成一个需要解释的问题。这套机制帮我们抓到过好几次回归——有一次是一个同事为了方便调试,在初始化里加了个 1Hz 的定时器,静态电流直接涨了 400µA,代码评审看不出来,功耗曲线一眼就看出来了。
6.3 批次一致性与产线筛选
实验室里测得再漂亮,量产之后还是要面对器件差异。影响静态电流的几个关键器件都有批次波动:
- MCU 的睡眠电流:数据手册上给的是典型值,最大值可能是典型值的 3~5 倍
- 电源芯片的静态电流:同样存在批次差异,而且随温度变化明显
- 晶振的频率偏差:影响守时精度
- 电容的漏电流:大容值陶瓷电容的漏电流可能到微安级
所以选型时有个习惯我一直坚持:看最大值,不看典型值。数据手册里的 Typ 是用来写宣传材料的,Max 才是你要拿去做最坏情况分析的。如果按典型值算出来的余量只有 20%,那量产批次里一定有超标的产品。
产线要不要做功耗筛选,取决于目标市场对续航的要求。如果产品定位是"一年换一次电池",那么 10% 的功耗超标可以接受;如果定位是"五年免维护",那每块板子都得测。产线测试最简单的做法是:整机烧录完固件后,进入一个专门的"功耗自检模式",静置 30 秒,测量平均电流,超阈值的板子直接剔除或标记。30 秒的工位时间换来的是一致性,我觉得很值。
7. 落地一套能回退的低功耗策略
7.1 分档设计:把功耗策略做成可配置
吃过几次亏之后,我现在所有的低功耗固件都会做多档配置,而不是一个写死的策略。典型的三档:
| 档位 | 唤醒周期 | 通信周期 | 平均电流 | 适用场景 |
|---|---|---|---|---|
| 省电档 | 10 min | 60 min | 10 µA 级 | 电池供电、数据变化缓慢 |
| 平衡档 | 1 min | 5 min | 50 µA 级 | 常规部署 |
| 性能档 | 5 s | 30 s | 300 µA 级 | 外接电源或调试期 |
配置项存在非易失存储里,可以通过上位机、网关或者本地按键切换。这么做的好处是显而易见的:现场调试不用重新烧固件,客户现场发现数据更新太慢可以临时切到性能档排查,排查完再切回省电档。
更关键的是,分档设计让"回退"成为一个可执行的选项。低功耗策略最怕的是"出了问题不好退"——如果代码里到处都是__WFI()和关机指令,想临时改成连续工作模式得改十几处。做成配置项之后,回退只是改一个数字。
7.2 兜底机制:宁可费电,不可失联
有些原则我认为是底线,不能为了省电去突破。
第一条:安全相关的功能不省电。如果设备有告警、保护、断电上报这一类功能,它的检测周期不能跟着低功耗策略一起拉长。我遇到过一个案例,团队把烟雾检测的采样周期从 10 秒改成 60 秒来省电,结果认证测试过不了——响应时间超标。低功耗策略的适用范围要显式划定边界,写进设计文档。
第二条:必须有链路自愈。设备连续多少周期没上报成功,就要降级到高功耗模式尝试恢复。具体做法是设一个失败计数器,失败次数超过阈值就缩短通信周期、提高发射功率、延长接收窗口,直到连上为止,连上之后再慢慢回到省电档。这个机制会让设备在异常情况下多耗一点电,但它保证的是"不会彻底失联"——对大部分应用来说,这是划算的交易。
第三条:保留一个可被唤醒的物理通道。深睡设备最容易变成砖:睡下去了,进不去,只能拆机。所以外场设备要留一个物理唤醒手段,比如磁铁触发霍尔传感器、按键长按、或者光敏器件。功耗代价极小(纳安级),救命价值极大。
7.3 迭代顺序:先砍最大的,再抠最小的
最后说方法。优化低功耗,很多人一上来就盯着 MCU 的睡眠电流抠那零点几微安,结果忙了两周省下 2µA,而旁边一颗上拉电阻还在稳定地吃 330µA。
正确的顺序是从大到小,每一轮砍掉当前最大的一项,重新评估,再砍下一个。用我们那个例子走一遍:
第一轮,功耗表上最大的三项是 MCU 睡眠 500µA、上拉 330µA、电源芯片 150µA。把 MCU 睡眠从 Sleep 降到 Stop2,500µA→1.5µA;上拉从 10k 改 1M 加门控,330µA→0.17µA;电源芯片换成低 Iq LDO,150µA→4µA。这一轮直接把 1.16mA 打到约 20µA。
第二轮,剩下的最大项是传感器常开待机 120µA 和通信 50µA。传感器改成深度关断加电源门控,120µA→0.1µA;通信周期从 60 秒拉到 15 分钟,50µA→3.33µA。这一轮打到约 12µA。
第三轮,剩下的都是微安级的小项了。这时候才值得去抠 MCU 的 GPIO 配置、确认调试口是否漏电、优化唤醒时序让唤醒时间从 5ms 降到 3ms。
三轮下来,收益分别是 98%、40%、10% 左右。投入产出比是断崖式下降的。如果你的项目时间有限,做完前两轮就可以收工了;第三轮的收益要跟"引入 bug 的风险"一起权衡。这也是我前面说的那个"平衡"——不是理论的平衡,是工期的平衡。
回到开头那批返修的设备。后来我们把功耗表重做了一遍,改了上拉、换了电源芯片、把 MCU 睡眠档位从 Sleep 降到 Stop2,现场实测平均电流从 1.16mA 降到 13µA 左右。返修率归零,但代价是设备响应上位机指令的延迟从即时变成最长 30 秒——好在业务上这个延迟是可以接受的,我们提前跟客户确认过。
我个人在实际操作中的体会是:低功耗设计真正难的地方不在技术,在于你必须在最开始就把所有代价摊开来,跟业务方一条条确认哪些能动、哪些不能动。技术上的每一微安都能打,但业务上的每一秒延迟都可能有人不接受。把这张账算在前面,比后面被返修单追着跑,要舒服得多。