1. 低功耗项目的真实痛点:单靠 LDO 为什么兜不住负载
先说一个我实际遇到的场景。手头做一块电池供电的无线传感器节点,主控方案选了低功耗 MCU,按数据手册上的睡眠电流算,一节 CR2032 撑几个月应该没问题。结果样机装上后,实测待机电流比预估高一截,而且无线发送时系统偶尔会复位。一开始怀疑 MCU 代码跑飞了,查了一圈,最后发现根子根本不在这里,而是电源方案本身撑不住:全程挂着一颗普通 LDO,待机电流基线被拉高,峰值负载时输出电压又被拖垮。
这类项目里,大家最常见的做法是“一颗 LDO 带全部”。器件少、电路简单,小电流应用好像也够用。但只要你把功耗预算认真算一遍,尤其是目标电流在微安级别、负载峰值在几十毫安甚至上百毫安脉冲的场景,LDO 方案很快就会显得力不从心。至少有三个绕不开的问题。
第一个问题是峰值电流能力。无线 SoC 在发射瞬间会拉出比较大的电流脉冲,持续时间几百微秒到几毫秒不等。LDO 的压差指标是按负载电流定义的,电流越大 Dropout 越大;当输入电池电压本身就比较低时,LDO 输出端的电压会被硬生生拉低,MCU 陷入欠压复位。你以为是软件不稳定,其实电源早就先崩溃了。
第二个问题是静态电流。低功耗器件省电,不代表供电链路也省电。普通 LDO 的静态电流 Iq 通常在几微安到几十微安之间,看似不高,但因为后面挂的负载电流基线可能连 10μA 都不到,LDO 本身反而成了最大的耗电点。如果系统里再放两三颗 LDO 分别给不同电压域,待机电流基线很容易突破 20μA、30μA,电池寿命的计算结果立刻惨淡。
第三个问题是电压域不灵活。低功耗系统的典型特征是“不同模式下需要不同电压”:运行模式要求高性能所以电压高一点,睡眠模式想压低功耗所以电压降到最低维持值,甚至直接关掉某些外围供电。LDO 固定输出,做不到动态调压,更谈不上按“负载状态”切换供电拓扑。这时候就需要一颗真正意义上的电源管理芯片,也就是 PMIC,来统一管理多条电压轨和多种工作模式。
正是为了解决上述问题,我在这块板子上重新设计了供电架构,选择用PCA9422做电源管理核心,配合PIC18F57K42做控制和状态监测。PCA9422 作为低功耗 PMIC,集成了多路 DC-DC 转换器和 LDO,支持 I2C 动态配置,休眠时能关断大部分内部电路,最大限度压低静态功耗;PIC18F57K42 则负责把负载的实时状态翻译给 PMIC,通过 I2C 下发电压切换指令,同时用片内 ADC 监控每一路电压轨的实际情况。这套组合跑下来,待机电流从原来的 20μA 级别降到了 2μA 左右,无线发送时的瞬时跌落也基本消失。
这篇文章就把这套方案从头到尾拆开讲一遍,包括系统拓扑怎么定、上电时序怎么设计、软件状态机怎么写、实测功耗怎么测、调试中踩了哪些坑。适合正在做电池供电设备、可穿戴设备或低功耗物联网节点的开发者参考。哪怕你不用这两颗芯片,里面对电源域划分和功耗管理的思路也是通用的。
2. 核心平台盘点:PCA9422 的电源通路与 PIC18F57K42 的控制接口
2.1 PCA9422 是一条可编程的电源总线
PCA9422 这颗 PMIC 面向的是低功耗 MCU、无线 SoC 这类负载,内部拓扑可以简单理解成“两路 DC-DC + 两路 LDO + 一组智能控制逻辑”。输入电压范围能覆盖单节锂电池的 2.8V 到 5.5V 范围,所以适配性比较强,常见供电来源如锂聚合物电池、两节碱性电池或者 USB 5V 输入都可以直接接。
我的用法是这样的:DC-DC1 给主控数字核心供电,DC-DC2 专门给无线射频前端;LDO1 给模拟传感器和信号调理电路,LDO2 作为常供电轨,给 RTC、备份寄存器这些需要全天候不断电的小负载。这样的好处是,射频和数字域的高动态电流由 DC-DC 承担,模拟域对纹波敏感,用 LDO 做一下后级滤波,各取所长。
PCA9422 的核心价值其实不在那几个转换器本身,而在于它把“电源管理策略”集中到了一个 I2C 配置的层面。你可以通过寄存器设置每路输出的默认电压、上下电顺序、开关频率、软启动时间,还可以在运行过程中随时改写输出电压目标值,这就是动态电压调节 DVS。换句话说,系统里原本需要用分立 MOS 管、负载开关、多组跳线实现的电源策略,被统一收编成了寄存器配置。
另外,PCA9422 的静态电流控制做得比较细。进入低功耗待机模式后,内部不必要工作的基准源和振荡器会关断,只保留仍然需要维持电压通道的最小电路。这一点对电池供电设备的全年待机特别重要。不过要注意,不同模式下的边界行为不太一样,用的时候一定要对着数据手册把每个模式的定义看清楚,特别是“睡眠模式”和“关断模式”对输出电压轨的保留策略是完全不同的。
2.2 PIC18F57K42 在电源管理里扮演什么角色
很多人会问:PMIC 自己就能管理电源,为什么还要拉一颗 MCU 进来?答案在于“谁来决定什么时候切换到什么电压”。PCA9422 能执行策略,但“策略本身”需要由知道系统当前状态的家伙来制定。PIC18F57K42 就是干这个的。
PIC18F57K42 虽然只是 8 位 MCU,但外设资源相当能打。先看控制侧:它有 MSSP 模块支持 I2C 通信,主模式速率和 PMIC 的通信需求完全匹配。再看监测侧:片内集成了带计算功能的 12 位 ADC,支持最多 6 个外部通道采样;内部还有一个固定参考电压 FVR,可以在不依赖电源电压的情况下提供校准基准。这意味着,MCU 可以直接在线监测电池电压、PMIC 输出电压、负载电流在采样电阻上的压降,所有采样数据还能通过 ADC 的计算功能自动做平均、放大、阈值比较,完全不需要 CPU 介入。
更关键的是 CIP(可配置逻辑单元)。这玩意可以理解成 MCU 内部的一组小型硬件逻辑门,你把它的输入输出接好之后,它可以独立于 CPU 实现类似“电压轨电压掉到阈值以下时立刻触发复位逻辑”这样的功能。传统方案里,这种保护逻辑要么靠外部比较器,要么靠中断里写代码。现在直接用片内 CLC 和比较器就能搭出来,节省了硬件面积,中断响应也更实时。
在低功耗方面,PIC18F57K42 提供了 IDLE、DOZE、SLEEP 等模式。运行模式下主频跑 64MHz 不在话下,进入睡眠后片内所需电路几乎全部停摆,唤醒源可以来自引脚电平变化、I2C 地址匹配或者定时器。这里有个容易忽略的优势:因为 I2C 总线是双向的,如果 PMIC 有中断输出,你可以把 PMIC 的状态变化直接映射成 MCU 的唤醒源,这让整机可以做到“PMIC 事件驱动 MCU 工作”,而不是 MCU 每隔几毫秒主动去轮询一次,白白耗电。
2.3 两颗芯片之间的硬件连线怎么定
接下来是系统级接线。我按实际用过的接法列一份清单,照着连基本不会错:
- I2C 部分:PCA9422 的 SCL、SDA 接到 PIC18F57K42 的 MSSP 引脚。上拉电阻用 2.2kΩ 比较稳,如果总线速率跑在 400kHz 或 1MHz,上拉阻值适当调低到 1kΩ 左右会更好;
- 中断反馈:PCA9422 的可编程输出引脚接 PIC 的 INTO 或 RP 引脚,用于上报电源就绪、低电压告警这类状态;
- 使能控制:PIC 的通用 GPIO 接 PCA9422 的使能引脚,可以手动控制 PMIC 是否进入关断模式;
- 电压采样点:DC-DC1 输出、DC-DC2 输出、LDO1 输出、电池输入各引一路分压电阻进 ADC 通道,分压比例以最高电压不超 ADC 参考电压为准;
- 电流采样:如果预算允许,在电池负极加一个采样电阻,用 PIC 内部运放差分放大后进 ADC,这样待机电流、发送电流都能实时看到。
上拉电阻这个细节容易被忽略。I2C 总线一上电默认高电平,如果 PMIC 还没准备好,总线上的状态可能被拉死。所以我在电路里预留了可拆卸的上拉,最初调试阶段先保证 MCU 侧上拉,等 PMIC 初始化完成后,再软件验证总线通信,不行就重新上电重来。这个问题在后面调试章节会细说。
3. 上电时序与电压域设计:先把电源骨架搭对
3.1 一个典型四路电源域的分配思路
不先把电源域规划好,后面写软件一定会来回返工。我在这类低功耗系统上总结出的原则是:按“负载类型”而不是按“物理位置”划分电源域。同一种性质、同一种控制策略的负载,尽量挂到同一路输出上。
用我手头这块传感器板子举例,四路电压轨分别是这样的:
| 输出通道 | 电压设置 | 供电对象 | 策略 |
|---|---|---|---|
| DC-DC1 | 1.8V | 主控 MCU 数字核心与 I/O | 运行/睡眠时动态调压到 0.9V~1.8V |
| DC-DC2 | 1.8V | 无线射频前端 | 仅在发射/接收期间开启 |
| LDO1 | 3.3V | 模拟传感器、运放、ADC参考 | 采样时开启,空闲时关闭 |
| LDO2 | 1.2V | RTC、备份 RAM、唤醒控制器 | 常开,永不关闭 |
这组配置的好处很明显:用电池供电时,除了 LDO2 的常供电轨,其余三路都可以在对应状态下被独立关闭或降低电压。睡眠时 DC-DC1 降到最低维持电压 0.9V,DC-DC2 和 LDO1 关断,整机功耗由 DC-DC1 的轻载静态电流和 LDO2 的负载决定,能做到极小。
3.2 上电顺序错了会怎样:一个具体实验
理论上,IC 们都能忍受同时上电,但实际工程上最好不要赌“都能忍”。我在这块板上做过一个对照实验:第一次把 PMIC 的四路输出全部配置成同时使能,一上电,系统 50% 概率出现 MCU 未能正常启动的现象,示波器上看 1.8V 电压轨先爬升,随后模拟域 3.3V 接通,整个波形上出现一个很深的回沟,看起来就像被负载拉死了一次。
原因是不同类型负载的输入电容差异很大:模拟传感器那一侧的旁路电容加起来可能到几十微法,上电瞬间充电电流非常大。如果四路同时软启动,电池输入端的瞬时电流可能超过供电回路的承受能力,导致输入电压短暂塌陷,已经建立起来的其他电压轨跟着回退。
修复方式是配置 PMIC 的上下电时序寄存器,把软启动顺序改成“LDO2 常供电域先行,DC-DC1 核心域其次,LDO1 模拟域再启,DC-DC2 射频域最后”。顺序本身没有绝对标准,核心原则是先建立低压、长供电时间的域,后启动高压、瞬态需求大的域。如果 PMIC 寄存器里没有完整的时序配置能力,也可以通过外部输出电容大小来控制启动时间差异,但效果远不如用内置时序控制来得可靠,每次开机的一致性也差一些。
3.3 输出放电与负载开关的坑
还有一个细节,很多人做电源域切换时翻车就翻在这里:PMIC 关闭某路输出电压之后,如果该路输出端挂着大容量电容,电压并不会瞬间掉到 0V,而是按电容放电时间常数缓慢下降。这个“假掉电”会导致后级器件认为电源没断,或者发生关机不完全的诡异现象。举例来说,射频前端关断后电压还有 1.2V,过一会儿某个引脚状态还保持在高电平,主控这边以为射频已经彻底复位,结果通信时序全乱。
解决办法是在每一路可关断的输出上预留一个下拉放电电阻,或者利用 PMIC 自带的输出放电功能。通常 PMIC 会提供“主动放电”选项,或者在需要关闭的通道上增加一个 MOS 管负载开关,关闭时对地短路。我实际使用时更倾向于增加负载开关的接法:一是放电速度可控,二是在放电完成后意味着来自电池的所有通路都被切断,避免 PMIC 的漏电路径影响低功耗指标。放电电阻的阻值要折中,太小的话关断后要多耗几十微安,太大又放电太慢,一般 10kΩ 到 100kΩ 之间调。
3.4 何时需要外接负载开关
如果 PMIC 的输出通道数不够,或者某路通道必须长时间开启而某个外围子模块需要单独断电,这时候就该上负载开关。负载开关选型关注两个参数:静态电流和导通阻抗。静态电流在低功耗系统里必须控制在微安级以下,导通阻抗则视负载电流而定,负载电流越大,阻抗造成的发热和压降越不可接受。另一个容易被忽略的参数是上升时间,负载开关的软启动时间决定了子模块上电瞬间的冲击电流,如果子模块输入电容大,尽量选择带内部软启动的型号,或者并一个小电阻限制上电速率。
4. 软件控制层:I2C 驱动、动态调压与监测逻辑
4.1 基础 I2C 驱动与总线健壮性处理
硬件连好之后,软件第一件事就是把 I2C 驱动写好。PIC18F57K42 的 MSSP 模块在主机模式下初始化并不复杂,但有几个设置项会影响后续稳定性。我贴一段初始化伪代码,具体寄存器地址因芯片型号不同会有差异,得结合数据手册确认:
// MSSP主机模式初始化: 400kHz, 7位地址模式 void PMIC_I2C_Init(void) { // 配置时钟源和波特率寄存器 // 400kHz 的目标速率需要根据 Fosc 计算并写入波特率寄存器 // 配置 MSSP 为 I2C 主机模式,开中断或轮询 // I2C 使能 }实际调 I2C 驱动时,比初始化更重要的是健壮性设计。PMIC 作为从机,存在“还没就绪”的时刻,比如整机刚上电那几百毫秒。若此时 MCU 复位重新执行初始化,I2C 通信可能收不到 ACK,程序就卡住。所以驱动里必须加超时机制,每次发送一个字节都设置等待上限,超过时间就报错并走重新初始化流程。超时参数也不要拍脑袋定,要考虑 I2C 总线上的最坏时序:时钟拉伸加从机内部操作时间,一般给 10ms 上限已经足够宽松。
另外,第一次通信建议先读 PMIC 的固定版本或 ID 寄存器,而不是直接写配置。如果读出来和预期不符,说明 I2C 地址、上拉、供电三项中的某一项有问题。这个“先读后写”的习惯在调试初期能省掉大量无意义查错。
4.2 动态电压调节 DVS 的实际用例
DVS 是本方案里最有价值的功能,没有之一。传统的电源策略是电压恒定,低功耗状态下靠 CPU 降频来省电,但降低主频后漏电功耗还是正比于电压的,频率对数字电路的动态功耗影响大,对静态泄漏电流则几乎没影响。真正能把静态功耗压下来的只有降压。
用这套 PMIC 实现 DVS 的流程是:MCU 通过 I2C 写入新的目标电压寄存器,设置 DVS 控制字段,然后触发电压切换执行。我把 DVS 应用在两个典型场景里。
场景一:主控核心电压跟随工作模式。CPU 全速跑业务时,DC-DC1 设置 1.8V;进入浅睡眠时,降到 1.0V。电压从 1.8V 降到 1.0V,数字核心的漏电功耗能下降 50% 以上。注意 MCU 进入睡眠前必须保证在当前电压下能顺利完成所有配置,降电之后的操作要尽量减少。
场景二:射频前端的按需供电。无线模块在 TX/RX 期间需要 1.8V 满电运行,其余时间完全不需要。我在驱动里封装了一个radio_set_power(bool on)函数,发送前先把 DC-DC2 目标电压配置为 1.8V 并使能,射频进入工作状态,发送完成后再次写寄存器关闭 DC-DC2。从“使能到输出稳定”这段窗口时间是固定的,需要和射频芯片的上电时序配合,一般预留几毫秒给 DC-DC 软启动和输出电容充电。
4.3 电压切换后要多长时间才能“认定”稳定
DVS 切换不是瞬时的。PMIC 内部基准变化、环路响应、输出电容充放电都需要时间。切到更高电压时,输出电压爬升;切到更低电压时,输出电压下降。对于后级负载来说,真正关心的是“电压什么时候进入目标范围且范围内不再抖动”。我做法是在 PMIC 切换命令发出之后,测量电压轨的采样值,连续三次采样都在目标电压范围内,才认为切换完成。这个流程用代码写也挺简单,设一个循环,每 1ms 读一次 ADC,最多等 20ms,超出就算超时报警。
很多低功耗架构师会在这里偷懒,直接用固定延时,看起来问题不大,但不同批次 PMIC 的切换时间随温度变化挺明显。温度低时转换器启动慢,固定延时容易踩边界;用闭环确认方式,虽然多花几十行代码,但是鲁棒性高不少。
4.4 ADC 监测链路的校准与滤波
光能调电压还不行,你得知道调整后实际输出是什么。PIC18F57K42 的 ADC 自带计算功能,可以用硬件完成多次采样平均,MCU 只需要读取最终结果。我配置了电池电压、DC-DC1 输出电压、DC-DC2 输出电压、LDO1 输出电压四个通道,轮流采样。
这里有一个容易误导新手的点:直接用 VDD 做 ADC 参考电压,看起来理所应当,但 VDD 本身可能被负载拉低,测出来的比例读数依然正确,换算成绝对电压值却错了。比如 MCU 工作在 1.8V,ADC 参考也是 1.8V,当 1.8V 轨跌到 1.6V 时,ADC 参考跟着跌,读到的 0x800 可能对应的是 1.6V 但代码里还以为是 1.8V,等于“同流合污”。所以温度漂移和精度要求高的场合,务必把参考电压配置成内部 FVR,FVR 可以输出固定 1.024V、2.048V 之类的精确值,只和硅片内部带隙基准相关,不随风摇摆。分压电阻的比值误差则可以通过校准系数修正:在首次装机时用精密万用表量一下实际电压,反推每路 ADC 的增益和偏置,把校准结果存到 Flash 里。
采样数据也不要做得太复杂。滑动平均窗口 8~16 次就够,窗口太大反而会把瞬态跌落滤掉,导致 MCU 看不到真实的欠压事件。低频的缓变信号用平均没问题,但要注意采样时序要错开 DC-DC 开关周期和射频脉冲,否则混入的纹波会影响判断。
5. 低功耗状态机与功耗测量:把调压策略变成可验证的结果
5.1 状态机的设计与电压表
电源管理代码的核心其实是一个状态机。我定义了四个状态:运行态、浅睡态、深睡态、关断态。每个状态的电源配置、CPU 行为、唤醒方式都不同,转换条件由事件驱动。
| 状态 | CPU 状态 | 电压轨配置 | 典型电流 | 唤醒源 |
|---|---|---|---|---|
| 运行态 | 正常执行 | DC-DC1 1.8V,DC-DC2 按需,LDO1 按需,LDO2 常开 | 10~80mA | 任意事件 |
| 浅睡态 | 关闭时钟外设,暂停计算 | DC-DC1 1.0V,DC-DC2 关,LDO1 关,LDO2 常开 | 20~50μA | 定时中断、GPIO |
| 深睡态 | 除唤醒控制器外全部停顿 | DC-DC1 关,LDO1 关,LDO2 常开 | 2~5μA | GPIO、RTC 定时 |
| 关断态 | CPU 完全掉电 | 仅 PMIC 待机电路和 LDO2 保持 | 1μA 以下 | PMIC 按键/定时唤醒 |
这张表建议贴在自己工位旁边,每次调功耗方案时对着表逐行检查。多数低功耗翻车都是状态机定义里的“应该关掉”和代码里“实际关掉”不一致导致的,表格能让你一眼看出漏网之鱼。
状态机切换时最关键的一条原则:绝对不能在降压还没完成时立刻关掉给主控供电的通道。比如从运行态进入深睡态,如果直接把 DC-DC1 关了,而 MCU 还在执行“进入睡眠”指令,结果就是 MCU 在执行中途断电,系统直接死机。正确顺序是:先把所有需要保存的状态写入备份寄存器,再设置唤醒源,然后配置 PMIC 降低电压或关闭通道,主控自己最后进入睡眠,等 PMIC 把电压轨处理得差不多,CPU 那段指令窗口已经过去了。
5.2 用序列电流记录验证整个状态迁移
写完状态机,需要一套能证明“功耗确实被压下去”的测量方法。最直接的做法是串电流表量平均电流:万用表串联在电池回路里,先看运行态电流,再看浅睡态电流,最后看深睡态电流。这个办法能测静态值,但对动态切换过程无能为力——你不知道从浅睡态切到深睡态时电流曲线是在哪个点掉下来的。
升级做法是买一个电流记录仪,设置采样周期 1ms 或 10ms,串在电池回路里连续记录一整天。跑完一轮状态机迁移,把数据拉出来看,每个阶段的电流都能对上状态切换的时间点。我实测中发现浅睡态到深睡态的切换竟然需要 600ms 电流才掉到位,打开状态切换日志一看,是 MCU 在关 DC-DC2 和 LDO1 之间多做了几次 I2C 寄存器回读,每次回读都拉高了总线电平。优化后把多次回读合并成一次连续事务,切换时间压缩到 80ms。这种问题不做动态测量根本发现不了。
示波器测瞬时波形也有讲究。电流探头是首选,测电池正极的电流波形,能清楚看到射频发送脉冲和电压切换脉冲的幅度、宽度。如果没有电流探头,可以用采样电阻方案,在电池负极串一颗 10mΩ 电阻,用差分探头或者 PIC 内部运放放大后看。示波器触发模式用单次触发或斜率触发,不然脉冲一闪而过很难抓住。
5.3 “假睡眠”的排查套路
低功耗项目中最多见的坑是“软件进入睡眠了,电流却没有降下来”。我趟过一回,现象很诡异:所有代码逻辑都认为 MCU 已经睡眠,深睡态电流还是在 10μA 以上。逐项排查之后,发现罪魁祸首是 ADC 通道的分压电阻。
我设计 ADC 采样电池电压时,电池正极到 ADC 引脚之间直接接了 100kΩ+100kΩ 分压网络,分压节点到地没有开关管。MCU 睡眠时,分压电阻内部没有断电,电池通过这两个电阻形成一条持续的泄漏支路:150kΩ 的等效电阻,按 3.6V 电池电压算,就是 24μA。这个电流比 MCU 睡眠电流大得多,直接把一整晚的功耗预算吃光。
解决办法是在分压网络的接地端串联一颗 NMOS 开关管,由 GPIO 控制。MCU 需要采样时,先把 GPIO 拉高、让分压网络接地、完成采样、再拉低断开接地端,这样采样电路只在采样瞬间耗电。这个“采样完成后必须切断分压支路”的原则适用于所有通过电阻直连电源的监测电路。另外,I2C 上拉电阻同样会在系统睡觉时形成漏电流,因为上拉电阻一端接 VDD 或 IO 电源,另一端在总线空闲时是高电平,不会漏,但如果总线被某个器件拉低,上拉上的电流就白白流掉了。低功耗状态机切换前,务必检查总线上是否有设备处于拉低状态。
6. 调试排错手记:I2C 卡死、上电瞬时跌落、待机电流升高的完整排查链路
6.1 案例一:I2C 总线卡死,写配置后 MCU 无法恢复
现象描述:系统上电后第一次写 PMIC 配置寄存器,MCU 在等待 ACK 的循环里卡死。用示波器量 SCL、SDA,看到 SDA 被拉低,始终不回弹。
排查链路是分几步走的。第一步,断开 PMIC 供电,测量 SCL、SDA 对地是否短路,排除焊桥和器件本身损坏;确认没问题后,检查上电顺序。我这边发现 PMIC 的 I2C 接口在实际供电建立之前不接受通信,如果 MCU 上电比 PMIC 快,就可能出现总线上已有数据但 PMIC 尚未就绪的窗口,MASTER 发出 START 后从机不应答,总线状态进入异常。第二步,检查通信地址是否配置正确。PCA9422 的地址和逻辑引脚的电平状态有关,按规格确认高/低/悬浮对应的地址位,我用示波器抓地址字节的位序人工解码,发现地址偏移了一位。第三步,检查是否有设备干扰总线,比如 PMIC 配置引脚被外部上拉到非预期电平。
最终根因其实是 PMIC 软复位后需要一段恢复时间,我的代码在上电后立刻发命令太早了。修复方式是:MCU 复位后延迟 10ms 等待 PMIC 内部上电时序完成,再执行“读 ID → 写配置 → 读回校验”三步曲。从此以后再没出现过 I2C 卡死。
这个案例给我的教训很直接:对从机电源域的时序要求一定要看数据手册里的上电波形图,但更重要的是在驱动层加“有限次重试后释放总线”的逻辑。I2C 总线协议本身无法自动恢复一个被从机锁死的 SDA,解决办法是把 SCL 切换成普通 GPIO,手动输出 9 个时钟脉冲,让从机释放总线,再重新切回 I2C 外设模式。这个“软件解挂死”的代码建议放进工程公共代码,谁用谁知道。
6.2 案例二:插入电池瞬间系统复位,启动波形出现凹坑
现象描述:用电源供电一切正常,一换电池上电就有概率复位。示波器抓 DC-DC1 输出,波形不是平滑爬升,而是爬到一半出现明显的回沟下拉,像是瞬间被重负载拉了一下。
排查链路从电源路径展开。第一步,测量电池座两端触点阻抗,发现接触电阻偏大,电池插入瞬间等效回路里串联电阻大,PMIC 启动时需要向四个电压轨输出电容充电,瞬时电流需求高,电池电压被拉垮。第二步,检查软启动配置。PCA9422 支持可配置的软启动时间,出厂默认往往比较短,我把它调长之后,充电电流峰值显著下降。第三步,检查输入电容。在电池输入正极和地之间、PMIC 的 VIN 引脚附近增加 10μF 陶瓷电容加 0.1μF 高频电容的并联组合,能大幅吸收上电瞬间的输入电流尖峰。第四步,调整上电顺序,错峰启动各电压域,让输入电流峰值从叠加变成错开。
最终组合方案是“加输入电容 + 拉长软启动时间 + 配置错峰上电顺序”,问题彻底解决。这个案例提醒我,电池供电项目的电源验证必须具备“最坏情况”思维:不只测正常情况下的上电,还得测电池快没电时的低电压上电,低温环境下的电池内阻升高会让问题放大。
6.3 案例三:深睡态电流偏高,逐层关断排查
现象描述:状态机切到深睡态,目标电流 3μA,实测 18μA。百思不得其解,因为 PMIC 配置和 MCU 睡眠模式都确认过。
按功耗问题排查的惯用套路,我从“外到内”逐层关断。先断开整个负载板,只给 PMIC 供电,观察 PMIC 自身静态电流。此时电流计显示 1.2μA,PMIC 是健康的。把 MCU 板接回去但 MCU 处于复位保持状态,电流 2.1μA。到这里还是正常。让 MCU 跑睡眠模式,电流却变成 18μA。
怀疑是某个 GPIO 在睡眠时状态不对,输出低电平导致外部器件导通。查所有 GPIO 的睡眠引脚状态配置,发现有一颗 GPIO 接了 PMIC 的某个使能引脚,睡眠前代码没有把它拉到正确电平,PMIC 的某路输出仍然保持,于是一直在供着某个外设的漏电。修正 GPIO 电平后,电流回到 2.9μA。
这个案例其实非常典型。低功耗系统的每一微安都值得较真,而 GPIO 引脚在睡眠模式下的默认状态往往是“保持睡眠前的值”,不是自动释放。写代码的时候,睡眠前必须梳理“睡觉期间所有引脚应该处于什么电平”,否则一个漏电路径就会毁掉整个 PMIC 调压策略换来的收益。建议在状态机进入深睡态的代码里,明确对每一个输出引脚赋值,而不是指望硬件复位默认值。
7. PCB 布局与最后一轮实战心得
7.1 布局布线上的几个关键约束
电源管理方案的 PCB 布局,比功能验证更能决定这个项目的长期可靠性。我在这块板子上踩出来的经验有这些:
- PMIC 必须尽量靠近供电对象。DC-DC 的开关节点越短,辐射噪声和振铃越少;大电流路径要短而宽,不要绕圈走细线;
- 输入电容放在 PMIC 的 VIN 引脚附近,不是放在电池连接器旁边。很多新手在这上面吃过亏,电容放远了就没有“吸收瞬态电流”的效果;
- 输出电容的地要单独接回 PMIC 的功率地引脚,避免模拟地或信号地共享大电流回流路径;
- 模拟部分的地和数字部分的地单点连接,LDO1 给模拟传感器供电时,输出端的取样点在负载端而不是 PMIC 引脚端,这叫开尔文接法,能减少走线电阻造成的测量误差;
- 电感选型时不要只看额定电流,还要看饱和电流必须大于峰值电流加 20% 的裕量。有些小体积电感 DCR 低但饱和电流不足,满负载一拉就饱和,效率反而急剧下降。
7.2 DVS 带来的继电问题:环路稳定性
动态电压调节不是只调输出电压那么简单。DC-DC 的环路补偿是按固定输出电压设计的,当目标电压大幅变化时,输出纹波、负载瞬态响应和目标电压变化率会互相打架。我实测中遇到一个现象:从 1.8V 动态降到 1.0V 后,DC-DC1 的输出纹波比原来大了将近两倍,原因是反馈分压网络在低电压时进入非最佳工作点。
解决办法有两个方向:一是充分利用 PMIC 提供的分压电阻配置选项,让内部反馈网络在不同电压区间的分压比尽量接近理想值;二是在软件层面控制 DVS 切换速度,不要瞬间跳变,而是分两步或三步递减到目标电压,给环路留出重新稳定的时间。这在低压大电流场景下特别有用。如果 PMIC 支持寄存器配置电压变化速率,强烈建议使用该功能,哪怕切换总时间多了几十毫秒,也比负载掉电复位强。
7.3 整个项目做完,我留下的几个判断
这套“PCA9422 + PIC18F57K42”的电源管理组合,最终在实测中达到了预期:待机电流 2.9μA,深睡态 1.8μA,无线发送峰值时 DC-DC2 动态调压正常,电池直插时的复位乱象消除。相比最初的 LDO 方案,保守估计同样电池容量下工作时间延长了 5 倍左右。
有一点我想特别强调:PMIC 加 MCU 的组合,本质上是在把电源管理从“一次性硬件设计”变成“软硬件协同设计”。硬件上你把各路电压轨、上电时序、放电回路搭好,软件上你用状态机和 I2C 控制把每微安抠出来。两者缺一不可。常见失败案例里,有些团队只重视 PMIC 选型,却忽视了软件状态机的精细度,导致 PMIC 能力再强也白搭;另一些团队把软件调得很花哨,但硬件上干扰和漏电路径一堆,功耗数字始终难看。
如果你也要上手类似方案,我建议第一步先别急着画原理图,拿参考设计跑一遍 PMIC 的全寄存器说明,明确每路输出的模式、时序、DVS 相关字段;第二步画好板子后先做电源域白盒测试,用万用表量每一路的静态电流;第三步再进入状态机编码。按照这个顺序做,能少走很多弯路。我现在每次拿到新的低功耗项目,都会先把“四路电压域的电流分配表格”列出来,再决定选哪颗 PMIC,也是这套方案留下的习惯。