做电池供电的便携设备,最绕不开的一件事就是电源。主控功耗没控制好,屏一亮电流就飙上去,待机又压不下来,电池续航天然就差一截。以前我惯用的做法是把功能拆散:一颗DC-DC给核心供电,一颗LDO给外设,再单独加充电芯片和电量计,四颗芯片把板子占得满满当当,调试时还要各自对接寄存器,光理清上电顺序就够喝一壶。后来换到PCA9422配STM32F469II这套组合,思路一下子简单了:PCA9422把充电管理、多路BUCK输出、LDO、电量计和动态电压调节全部集成进去,STM32F469II通过一根I2C总线就能把整个电源面管起来。这篇文章就把这套方案从选型、硬件搭线、驱动开发到低功耗调优的完整过程写出来,顺便把那些常规文档里不会写的坑也一并整理清楚。
适合谁来读其实挺明确:一类是硬件工程师,想确认PCA9422各电压轨怎么接外围、电感电容怎么选;另一类是嵌入式软件工程师,需要写I2C驱动、搭电源状态切换和做功耗优化;还有一类是做方案评估的,在犹豫要不要把传统的“DC-DC加充电芯片加电量计”方案整体换成PMIC。无论哪类读者,跟着下面的寄存器配置和时序设计走一遍,基本等于把一个可投产的电源子系统从零搭完了。
1. 为什么选PCA9422加STM32F469II这套组合
1.1 需求驱动的方案选型
先交代这套系统的背景。一个典型的便携式数据采集终端,主控是STM32F469II,Cortex-M4F内核跑到180MHz,带TFT-LCD控制器和SDRAM接口,外设挂了触摸、SD卡、姿态传感器和通信模块,整机用单节锂电池供电。最初的需求列下来有这么几条:
- 主控和LCD需要多路独立电压轨,彼此之间要有明确的时序关系,不能一上电全怼出来;
- 电池要支持USB充电,还要能估算剩余电量,不能只靠电压查表那种粗糙办法;
- 设备有低功耗待机需求,MCU要进Stop/Standby,电源端必须跟着切状态,把外设轨彻底断掉;
- 部分外设逻辑在性能档和节能档切换时希望同步调整供电电压,也就是动态电压调节。
这种需求如果用传统方案做,至少四颗芯片起步:BUCK给主控、LDO给传感器、充电IC管理电池、电量计做电量估算,外围还要搭配功率电感、采样电阻、分压电阻,PCB面积和BOM成本都下不来。更麻烦的是芯片来自不同供应商,寄存器风格完全不统一,软件层得写四套驱动,出问题时排查链路特别长。
PCA9422这种高集成PMIC恰恰把上述痛点一次性解决了。单颗芯片内部同时包含多路降压转换器、LDO、线性充电管理、电量计和I2C从机接口,MCU只需要通过寄存器操作就能控制每一路输出。对STM32F469II这种偏重性能和外设的主控来说,它自己本身不含完整PMU,必须依赖外部电源管理,而PCA9422的集成度正好匹配这类“一颗主控加一大帮外设”的系统。
1.2 PCA9422的管理边界
很多人第一次看到PCA9422会误以为它是“万能电源芯片”,其实它的定位非常清晰:面向单节锂离子电池供电的便携设备,输入电压范围大概在2.7V到5.5V,刚好覆盖锂电池从放电截止到充满的整个区间。它能管的是电池输入到各路输出的电源转换、充电、保护、电量估算和状态监控。
芯片内部我按功能区分为这么几块:
- 多路BUCK降压转换器,为主控和数字外设提供高效率电源轨,支持通过I2C调整输出电压;
- 一路LDO,适合给RTC、备份域或者对噪声敏感的低功耗模块供电;
- 电池充电管理,支持CC/CV充电流程,充电电流和终止电压可配置;
- 电量计模块,累计电池充放电状态,输出剩余容量参考;
- I2C从机接口和中断输出,让MCU可以随时读写寄存器、接收电源事件。
只看这一串功能就会发现,它替代的是过去分立方案里“电源转换加充电加监测”的一大半工作。但“完整电源管理”不等于“全部电源工作”,外部仍需配置合适的输入输出电容、功率电感、NTC温度检测电阻等。做系统设计时要分清楚边界:PCA9422负责策略执行,真正的功耗策略还是得由STM32F469II里的软件来定。
1.3 STM32F469II对电源轨的硬性要求
STM32F469II这颗主控的供电要求其实很典型。它的VDD引脚的正常工作范围是1.7V到3.6V,但实际工程中很少有人敢把主控电压压到1.7V附近去用,一般还是给稳定的3.3V,同时要求电压纹波不能影响ADC采样和高速接口的稳定性。除了主VDD,还有独立的VDDA给模拟域,VBAT给备份寄存器和RTC,如果接了外部SDRAM,还需要额外的1.8V或2.5V供电轨。
从功耗角度看,这颗MCU运行时的电流跟主频、外设开关情况强相关。跑满180MHz加上LCD刷新和SD卡读写,系统电流冲到100mA以上很正常;进Stop模式后外设全关,电流能降到几百微安;再往下的Standby模式,配合RTC,可以做到微安级别。这三种模式之间切换,电源端必须快速响应:从几十毫安跳变到几百微安时,BUCK不能因为轻载效率差反而把静态功耗做大;从Stop模式唤醒回到满负载时,输出电压不能有明显跌落,否则MCU会直接复位。
这套需求推演下来,PCA9422的低功耗特性和I2C可配置能力刚好能对接上。BUCK在轻载时可以切到省电模式,LDO专供待机域,MCU休眠前通过I2C关掉外设轨,唤醒后再恢复,整个电源策略都是可编程的,而不是靠一堆硬件跳线写死。
2. 系统架构与供电拓扑设计
2.1 整机供电链路
整机供电链路我建议完全围绕PCA9422的输入输出能力来设计。系统只有两个主电源入口:一个是锂电池,直接接到PCA9422的电池端;一个是USB的5V,进入PCA9422的充电输入引脚。PCA9422内部根据充电状态自动管理这两路输入,不需要外部做复杂的电源路径切换。
输出侧按用途分成几路:
锂电池 ──► PCA9422 VBAT ├── BUCK1 ──► VDD_3V3 给STM32F469II主电源和数字外设 ├── BUCK2 ──► VDD_1V8 给SDRAM和逻辑电平接口(支持DVS) ├── BUCK3 ──► VDD_2V8 给LCD模块、触摸和传感器 ├── LDO ──► VDD_3V0 给RTC备份域和唤醒逻辑 └── 充电管理 ──► USB VBUS输入这套拓扑的核心思路是“哪一路需要维持待机,哪一路只在运行时打开”要分得清清楚楚。BUCK1虽然供给主控,但MCU进入Standby后其实可以把BUCK1关掉,只留LDO给唤醒逻辑供电;BUCK2和BUCK3完全是外设轨,休眠时直接关断;如果系统需要RTC在整机断电后继续走时间,LDO输出则要保持常开,同时给RTC供电的路径上要放一个小的备份电容,防止电池突然断开时RTC数据丢失。
有一个很容易忽略的点:电池电压会随着放电从4.2V一路降到2.7V,BUCK的输入电压范围必须始终覆盖这个区间。PCA9422的输入下限在2.7V左右,意味着即便电池放得很空,只要还能提供一定的负载电流,BUCK1的3.3V输出仍然能维持。实际项目中我通常把电池保护板的欠压点设置在3.0V左右,留出余量,尽量不触发PMIC的输入欠压保护。
2.2 电压轨规划与电流估算
电压轨的规划不能拍脑袋,每一路的最大负载电流都要先估算一遍再定储备。以STM32F469II跑180MHz为例,主控本身峰值电流往60到80mA估算,加LCD背光、SD卡写操作,BUCK1的峰值负载可以按150mA算。BUCK2如果接SDRAM,DDR器件在突发读写时电流变化很快,按80mA估算。BUCK3主要是LCD和传感器,按60mA估算。这些数值叠加起来,整机瞬时功耗大概在300mA级别,锂电池容量如果做到1000mAh,正常混合使用撑一到两天问题不大。
我把电压轨的规划整理成一张表,方便对照:
| 电压轨 | 去向 | 典型电压 | 预估峰值电流 | 来源 |
|---|---|---|---|---|
| VDD_3V3 | STM32F469II VDD/VDDA、SD卡、接口电平 | 3.3V | 150mA | BUCK1 |
| VDD_1V8 | SDRAM、部分IO逻辑 | 1.8V,可降至0.9V | 80mA | BUCK2 |
| VDD_2V8 | LCD模组、触摸、传感器 | 2.8V | 60mA | BUCK3 |
| VDD_3V0 | RTC、备份域、唤醒控制 | 3.0V | 3mA | LDO |
| VBAT | 锂电池直供 | 2.7V~4.2V | 整机电流 | 电池 |
这里有个设计细节值得单独说。BUCK2这一路我特意标注了“可降至0.9V”,这就是PCA9422的DVS功能发挥作用的地方。那套外设逻辑模块在正常性能模式下需要1.8V供电才能工作,但在低功耗监听模式下,只要维持数据不丢,电压降到0.9V就行。电压降一半,动态功耗理论上能差好几倍,这种收益在整机功耗里的体现非常明显。
电流估算表做完之后,我习惯再给每路预留20%到30%的余量。这个余量不是为了硬件,而是为了后续软件迭代时新增功能不用再改板子。一套电源方案如果只卡着当前需求设计,往往一次固件升级就把余量吃掉了,后面再改PCB成本极高。
2.3 上电时序怎么定
上电时序是整套系统里最容易被轻视、出问题最隐蔽的一环。MCU对电源轨的上电顺序有严格要求,尤其是带有外部SDRAM和LCD控制器的芯片,如果IO电平先于主电源稳定,IO口可能通过内部二极管向上反灌电流,导致芯片进入不确定状态。
PCA9422的好处是它的BUCK和LDO可以通过寄存器配置使能顺序。我的实际设计是先让LDO输出VDD_3V0,给RTC和备份域供电;稳定几毫秒后打开BUCK1输出3.3V,等主控VDD起来;再延迟一段时间打开BUCK2和BUCK3,让外设轨在主控初始化完成之后再上电。最后,MCU的复位信号必须等所有电源轨OK之后才释放,这一步通常由外部复位芯片或者PCA9422的电源OK信号来控制。
按这个思路排下来,上电顺序表大致是:
| 顺序 | 动作 | 延迟 | 目的 |
|---|---|---|---|
| 1 | LDO输出VDD_3V0 | 0ms | 先给待机域供电 |
| 2 | BUCK1输出VDD_3V3 | 5ms | 主控核心电源稳定 |
| 3 | BUCK2输出VDD_1V8 | 10ms | SDRAM等逻辑上电 |
| 4 | BUCK3输出VDD_2V8 | 15ms | LCD和传感器上电 |
| 5 | 释放MCU复位 | 20ms | 主控开始启动 |
这个时序并非越快越好。如果MCU复位释放得太早,BUCK2的1.8V还没建立,SDRAM控制器初始化必然失败;如果复位释放得太晚,又会影响冷启动速度。我在实际项目中把20ms作为参考值,具体延迟还是要在示波器上抓波形确认,每颗芯片的软启动时间有差异,不能完全照抄。
3. I2C驱动与寄存器配置实战
3.1 物理连接与地址探测
PCA9422作为I2C从机,和STM32F469II的连接极其简单,SDA和SCL两根线加上共地就行。需要注意的一点是I2C的电平必须匹配。如果MCU的I2C外设工作在3.3V,PCA9422的I2C逻辑电平引脚也要接3.3V;如果是1.8V系统,就接1.8V。电平不匹配轻则通信不稳定,重则直接损坏引脚。上拉电阻一般取2.2k到4.7k,具体根据总线电容和通信速率调整。
从机地址不是一个固定的神奇数字,而是由芯片的地址引脚电平决定的。所以我在每个项目的驱动开发第一步,不是去手册里查一个地址出来硬编码,而是写一个小扫描函数把0x01到0x7F全扫一遍,然后看哪个地址有ACK响应,再把实际地址回填到驱动配置文件里。这样做的好处是避开了“手册看错、实际地址不一样”的经典翻车现场。
确认地址之后,第一步永远是读ID或版本寄存器,确认芯片活着,顺便核对固件版本。这一步别跳过,很多看似诡异的问题,最后发现是芯片型号批次不同,寄存器行为有细微差异,读一下ID就能定位。
3.2 BUCK的配置和电压切换
BUCK输出配置的核心是写电压寄存器。PCA9422的输出电压不是简单写个电压值,而是用8位电压码来表示,实际电压和电压码之间存在线性关系。代码里我习惯封装一个通用函数,接收目标电压值,内部自动计算电压码:
uint8_t pmic_voltage_to_code(uint16_t voltage_mv) { /* 假设步进为6.25mV,基准从600mV开始 */ return (uint8_t)((voltage_mv - 600) / 6.25); }这个公式里的基准确认方式很简单:手册里会给出电压范围和步进值,套进去算一遍,再反查几个典型电压,能对得上就没问题。有些PMIC还支持动态电压调节,也就是MCU在运行过程中通过I2C随时改写输出值,这种情况下电压码的计算必须足够可靠,写错一个码,输出可能直接跳到错误电压,轻则外设工作异常,重则芯片损坏。
使能BUCK的流程我按四步走:
- 读当前状态,确认BUCK处于安全状态;
- 写目标电压码,先不让输出使能;
- 写使能位,打开BUCK;
- 轮询电源OK标志,确认输出已经建立。
重点是第一步和最后一步。很多人直接跳过读状态和电源OK,写完就以为电已经出来了,结果查了半天发现是使能位被此前配置的状态机锁住了,或者负载太大导致BUCK保护。轮询电源OK标志是个好习惯,哪怕只跑一次确认寄存器值,也能把一大堆玄学问题提前拦下来。
3.3 DVFS动态电压调节的落地
PCA9422的DVS功能是我选它的一大理由。DVS的核心思路是电压跟随性能需求变化:系统需要高性能时给出高电压,进入低负载时就把电压降下来,让动态功耗随电压平方关系下降。它和传统的固定电压供电最大的区别就在“动态”二字。
落地时最关键的一条原则是“先加压再升频,先降频再降压”。频率和电压是配套的,如果先升频再加压,高频状态下电压不够,电路时序余量不足,跑着跑着就出随机错误;如果先降压再降频,低电压状态下还跑着高主频,同样有问题。我一般这样封装性能档位切换:
void set_performance_level(bool high) { if (high) { pmic_set_voltage(PMIC_BUCK2, 1200); /* 先抬电压 */ system_set_logic_clock(100); /* 再拉高频率 */ } else { system_set_logic_clock(40); /* 先降频率 */ pmic_set_voltage(PMIC_BUCK2, 900); /* 再降电压 */ } }实际测试这个函数,在高低档之间切换,BUCK输出电压能在大约几十微秒内完成斜坡过渡,系统逻辑运行稳定,纹波也没出现明显恶化。PCA9422的DVS还允许配置斜坡速率,如果担心瞬时负载变化导致电压塌陷,就把斜坡调慢一点,保证负载电流逐步上升;如果希望快速进入高性能状态,就调快斜坡,缩短电压爬升时间。这个参数建议在原型阶段多试几个值,找到功耗和稳定性的平衡点。
3.4 中断与事件处理
电源芯片很重要的一类信号是中断。PCA9422会把电池电量低、充电完成、充电中、过压、过温等事件通过中断引脚告诉MCU。STM32F469II这边可以把中断引脚接到一个支持外部中断的GPIO上,用下降沿触发。
中断响应流程我建议保持简单:中断来了先读PCA9422的中断状态寄存器,确认事件源,清中断标志,再执行对应处理。不要一进中断就做复杂操作,PMIC寄存器读写在中断里来回搞很容易把I2C总线拖慢。我的做法是中断处理里只做事件标记和必要的最小操作,剩下的逻辑放主循环或者RTOS任务里执行。
比如电量低中断,处理逻辑就是:进中断,读状态确认是低电量事件,清标志,置一个低电量标志位,然后退出中断;主循环里发现标志位置位,保存采集中间数据,关闭外设,提示用户充电。如果试图在中断里完成整套关机流程,占用的时间太长,而且I2C通信失败时缺乏重试机制,很容易卡死。
4. 硬件设计与PCB布局避坑
4.1 功率部分的外围选型
PCA9422的BUCK外围看起来和普通DC-DC类似,输入电容、输出电容、功率电感各就各位,但参数选择直接影响效率和纹波。我在项目里用的典型配置是:输入电容10uF加100nF高频电容并联,输出电容22uF两到三颗并联,功率电感2.2uH到4.7uH。感值选大一点,轻载效率更好,但瞬态响应会变差;感值小,纹波电流大,但瞬态响应快。这中间没有绝对最优解,只能看系统最常用的负载区间来决定。
如果系统平时大部分时间在几十毫安负载下运行,我建议选大感值,让BUCK更容易进入省电模式。如果系统负载经常在零到几百毫安之间快速跳变,比如SD卡写入、无线发射,那应该选小感值,配合稍大一点的输出电容,优先保证瞬态不掉压。这个权衡我每次都会写在原理图备注里,避免后续改板时有人随手换个电感导致性能大变。
LDO的外围相对简单,输入输出各加一个1uF陶瓷电容即可。LDO主要给RTC、备份域供电,负载电流很小,关键是输入端不要和BUCK的输出靠得太近,免得开关噪声串进低功耗域。
充电路径的布线值得单独强调。USB的5V进来之后,先经过ESD保护器件,再进入PCA9422的USB输入引脚,这条路径要尽量短,线宽加粗,因为充电电流可能到500mA甚至1A。如果线宽不够,充电时压降过大,充电管理芯片会误判输入电压不足,降低充电电流,充电速度慢得让人抓狂。
4.2 开关电源的布局禁忌
开关电源布局的核心是让高频电流环路最短。BUCK在开关过程中,输入电容、功率管、续流管、输出电感之间会形成高频脉动电流,如果环路面积大,就会向外辐射电磁噪声,同时带来纹波恶化。
我在画PCB时定了两条硬规矩:第一,输入电容必须紧贴PCA9422的电源输入引脚,中间不要放过孔,让高频电流走最短路径;第二,功率电感靠近芯片输出引脚放置,输出电容紧贴电感后端。反馈和远程采样线如果存在,要尽量远离电感和开关节点,不要平行走线。I2C、中断这些信号线,可以走内层,包地处理,避免被开关噪声耦合。
还有一点是散热。PCA9422这种小型化PMIC的散热主要靠底部焊盘和PCB铜皮,原理图设计时就要保证芯片下方有完整的接地铜皮,并打上过孔阵列连接到内层地平面。不要为了省事在芯片下方只留几个细线,那样芯片温度会明显偏高,尤其充电和满载BUCK同时工作的时候,热积累很不利于长时间稳定运行。
4.3 电量计校准的硬件要点
PCA9422内置的电量计,从硬件角度要说两句。电池温度检测引脚一定要接NTC热敏电阻,NTC的位置要贴近电池本体,而不是放在PCB上远离电池的地方。温度采样不准,电量计的容量补偿就会偏差,冬天和夏天的续航估算差异会差得离谱。
另外电池到PCA9422的采样路径上不要随意串电阻。很多工程师习惯在电池正极串一个采样电阻做外部电流检测,但如果PMIC内部已经有电量计,外部电阻反而可能干扰内部采样。如果确实需要外部保护,也尽量用小阻值器件,并且让PCB走线尽量对称,避免引入额外压降。
硬件做好这一步还不够,电量计的标校还得靠软件配合,下面的章节再展开。
5. 软件框架与电源状态机设计
5.1 驱动分层怎么分
电源管理软件最忌讳把所有寄存器操作都堆在业务代码里。PCA9422的寄存器很多,业务代码直接操作寄存器,一段时间后就会变成一团乱麻。我习惯把代码分成三层:
第一层是硬件抽象层,封装I2C读写和基础寄存器操作,提供pmic_read(reg)、pmic_write(reg, val)这类接口;第二层是功能层,把“设置BUCK电压”“打开LDO”“读充电状态”这些功能封装成函数;第三层是策略层,向上提供“进入低功耗模式”“切换性能档位”“处理低电量关机”这类语义化接口。
策略层和功能层分离还有个实际好处:测试时可以方便地替换掉真实芯片。比如在PC上做单元测试,策略层调的是抽象接口,底层可以模拟,不依赖真实硬件就能验证休眠流程的调用顺序是否正确。这对后期维护太重要了,否则每次都要拿示波器去抓实际波形才能确认逻辑。
5.2 运行、睡眠、关机三态切换
电源状态机是这套软件的骨架。我根据设备实际使用场景定义了四个状态:运行态、睡眠态、深度待机态和关机态。每个状态对应一组MCU外设配置和PCA9422输出配置。
运行态下所有BUCK都开启,STM32F469II跑满性能,外设正常供电。睡眠态的含义是系统暂时不干活了,但仍然能被定时器或外部按键快速唤醒,这时候MCU进Stop模式,BUCK2和BUCK3关断,BUCK1保持供电,唤醒延迟控制在百毫秒以内。深度待机态则对应长时间不操作,MCU进入Standby模式,BUCK1也关掉,只保留LDO给唤醒逻辑和RTC供电,待机电流做到微安级。关机态就是完全断电,LDO是否保留取决于产品是否需要RTC在电池取出前持续走时。
状态切换的代码顺序非常讲究。以运行态切到深度待机态为例:
void enter_deep_standby(void) { save_system_context(); deinit_lcd(); deinit_sd_card(); pmic_set_buck(PMIC_BUCK3, OFF); pmic_set_buck(PMIC_BUCK2, OFF); pmic_set_buck(PMIC_BUCK1, OFF); /* 最后进入MCU的Standby模式 */ HAL_PWR_EnterSTANDBYMode(); }这段代码里关BUCK的顺序有讲究,从离MCU最远的外设开始关,最后关主控自己用的BUCK1。如果反过来先关BUCK1,MCU供电消失的瞬间I2C还在通信,就会出现写一半掉电,寄存器状态不确定的脏数据问题。我在调试中最开始就是踩了这个坑,导致休眠后重新唤醒时某一路BUCK一直处于非法状态。
唤醒流程则正好相反:唤醒源产生中断,LDO保持供电使能唤醒信号,MCU先启动,然后初始化I2C,打开BUCK1,等待电源OK,再打开外设轨,最后恢复运行态。整个过程要在几十毫秒内完成,所以唤醒路径上的代码要尽量精简,不要在启动初期做太耗时的初始化操作。
5.3 RTOS环境下的电源管理
如果系统跑了RTOS,电源状态切换不能直接在一个线程里憋到底。用FreeRTOS这类系统时,休眠操作应该在所有任务都被挂起、系统空闲钩子函数里触发,而且要确保没有任务在等待I2C信号量。休眠前要把I2C总线释放,否则唤醒后I2C可能因为标志位错乱而首次访问失败。
我建议的做法是把电源状态切换做成RTOS的一个独立任务,使用事件标志或者消息队列接收请求。业务任务需要进休眠时,先向电源管理任务发送请求,然后自己在临界区挂起。电源管理任务收到请求后,暂停所有非关键任务,执行关闭外设、拉低电压、进入Stop模式。唤醒后由唤醒源触发中断,优先恢复电源管理任务,再逐个恢复业务任务和驱动状态。
这种做法的好处是所有电源动作在同一个任务里串行化,不会出现两个任务同时操作I2C导致总线仲裁冲突的问题。实际项目中用事件组来做状态同步比较顺手,休眠前等待所有业务任务都进入挂起状态再去碰PMIC寄存器,能避免很多随机性很强的异常。
6. 实测数据与功耗调优心得
6.1 功耗测量方法
一开始我用电表串联测电流,但发现一个坑:普通万用表在毫安级和微安级之间切换档位时,换挡瞬间会有不小压降,会干扰系统运行。后来我改用精密电流采样配合示波器记录,或者直接用带记录功能的功耗分析仪。测待机电流时,板子要断电充分放电后再进待机态,否则电容里的残留电荷会掩盖真实功耗。
测纹波用示波器探头测量时,要尽量使用短地线弹簧而不是长探头地线,长地线会形成一个环路天线,测出来一堆虚假高频噪声。我把带宽限制设为20MHz,再观察峰值。对3.3V轨来说,纹波控制在50mV以内是比较理想的状态,超过100mV就要考虑是电感选型问题还是layout问题。
6.2 场景化实测结果
我把这个系统在几个典型场景下测了一轮,数据做成了表格,方便直接对照:
| 工作模式 | 系统状态 | 实测电流 | 输出纹波 |
|---|---|---|---|
| 全速运行 | MCU 180MHz,LCD刷新,SD卡读取 | 83mA | 38mV |
| 运行节能 | MCU 80MHz,关闭LCD,DVS降到0.9V | 21mA | 30mV |
| Stop模式 | 外设BUCK关闭,BUCK1保持 | 310uA | 12mV |
| Standby模式 | BUCK全部关闭,LDO待机域 | 3.2uA | 8mV |
| 关机 | 全部关闭 | 0.9uA | - |
这个数据是在1000mAh电池下测的。如果设备每天深度待机16小时,全速运行2小时,其余时间睡眠,平均电流大概在10mA左右,理论续航能到100小时左右。实际使用中电池老化和温度影响会缩水,但整体续航表现已经远超之前用分立LDO方案时的水平。
DVS的收益在数据里看得很清楚。同样的逻辑模块,从1.8V降到0.9V供电,功耗从21mA降到约8mA(配合降频),这个降幅完全靠电压的变化拉出来。对长期处于监听模式、偶尔短时间高负载的设备来说,DVS带来的续航收益是非常可观的。
6.3 参数微调的几个经验
实测之后必然有一轮参数微调。我在这个项目里调整过三个参数,每个都直接影响功耗和稳定性。
第一个是BUCK的电感感值。最初用2.2uH,轻载时PFM模式切换点不够激进,待机功耗偏高;换成4.7uH之后轻载效率明显改善,但瞬态响应变差,经过权衡保留了3.3uH作为折中。
第二个是DVS的斜坡速率。斜坡调快,电压切换过程短,功耗浪费少,但瞬时负载变化时会看到电压塌陷;调慢之后电压稳定,但切换过程多了几毫秒,低负载时省下的功耗又被拖回去了。最后我根据系统最频繁的性能切换场景选了一个中间值。
第三个是充电终止电流。锂电池充电时,如果终止电流设得过高,电池还没完全充满就停止充电,看起来充到100%,实际离满充还差一点;设得过低,充电尾段拖着时间太长。我用100mA作为终止电流参考,再结合充电截止电压和电池内阻做了小幅修正,充满后电池电压能稳定在标称值附近。
7. 常见问题与排查技巧实录
7.1 上电后主控完全不跑
这类问题我遇到至少三次,每次都花了不少时间。现象是STM32F469II上电后不运行,调试器连不上,量所有电压轨都有输出,看着一切正常。最后定位到的原因基本都是复位时序问题,MCU的复位信号在电源没有完全稳定的情况下就已经释放,导致主控在电压爬升中间启动,内部逻辑初始化失败。
排查思路是拿示波器同时抓BUCK1输出波形和复位脚电平,看它们的时间关系。正确的状态是复位脚保持低电平,等BUCK1输出完全稳定之后再拉高。如果发现复位拉高早于电压稳定,就在复位芯片的延时配置上做调整,或者在电源OK信号和复位之间加一级RC延时。这个问题在新画的PCB上尤其常见,因为原理图设计时把复位芯片的延时设置默认成最小值了。
7.2 I2C扫描不到PCA9422
I2C扫描不到地址,先不要怀疑芯片坏了。最常见的原因是上拉电阻的电压不对,PCA9422的I2C逻辑电平和MCU不在同一个参考电压下,当芯片侧供电还未建立时,I2C引脚可能处于未定义状态,总线直接拉死。用万用表量SDA和SCL对地电压,正常空闲状态下应该是上拉电压的高电平,如果看到0V或者接近0V,要么上拉没接,要么有器件把总线拉住了。
另一个容易忽略的原因是I2C速率。PCA9422这种PMIC一般最高支持1Mbps,但有些芯片在400kHz以上兼容性不好,尤其是长线连接时。我在代码里初始化为100kHz标准模式,扫描基础地址,确定通信正常后再慢慢提速率。如果100kHz下通信稳定、400kHz就不行,基本就是PCB布线寄生电容过大或者上拉电阻选小了。
7.3 轻载时电池耗电异常快
如果我看到整机待机电流远高于数据手册“标称值”,第一反应是某个该关的BUCK没关掉。很多人只关了外设的供电使能,但没配置输出放电功能,BUCK输出电容上的残余电荷会缓慢漏下去,形成额外消耗。PCA9422如果有输出放电寄存器,关断输出时要一并打开,让输出轨快速放电到零。
还有一种情况是BUCK跑在强制PWM模式。PMIC一般会根据负载电流自动切到省电脉冲模式来降开关频率,但Debug调试时如果强制配置了PWM模式,轻载功耗会明显上升。排查时读一下模式配置寄存器,确认运行模式是否允许自动切换。
7.4 动态调压瞬间电压跌落导致复位
这个坑主要出现在DVS使用初期。我原本以为写个电压寄存器就完事了,结果在性能档切换时,SDRAM访问瞬间系统直接复位。用示波器看BUCK2电压,发现在降压过程中电压先掉到正常值以下一大截,负载稍重就触发欠压复位。
排查后确认是斜坡速率和负载配合不佳。调电压的斜坡时间如果太短,输出电容放电速度跟不上参考电压的变化,就会出现下冲。解决方法是调长DVS斜坡时间,同时保证在电压切换期间,重负载外设先进入空闲状态,等电压稳定后再恢复访问。代码里相当于把“电压切换”和“任务调度”做了一次互斥,切换完成前不恢复SDRAM和高速外设操作。
7.5 电量计越用越不准
电量计不准是很多便携设备的通病,原因多数不在硬件,而是没有周期性的满充满放学习。PCA9422的电量计需要知道电池的当前满充容量和截止容量,这两项会随电池老化变化。系统需要在每次充满电后记录充电容量,每次放到截止电压后记录放出容量,把这些数据回写到校准寄存器,让电量计内部模型更新。
如果设备很少有机会完整放空再充满,电量计会长期处于“猜测”状态。我建议在固件里加一个校准周期,比如每两周提示用户做一次完整充放电;或者利用产品出厂前的老化测试阶段,专门做一次满充满放校准,把校准结果固化进默认参数里。这样电量计在用户手里的初始精度会好很多。
这套电源方案我前后调了三版才稳定下来,最深的感觉是“电源管理”四个字里的坑,多半不是芯片本身带来的,而是时序、布局和状态切换这些细节堆出来的。PCA9422和STM32F469II的组合在硬件上集成度足够高,剩下真正要打磨的是软件状态机和板级细节。最后再分享一个实用技巧:把PCA9422的中断输出接到STM32F469II一个能唤醒Standby模式的IO上,配合LDO常供的唤醒逻辑,关机态到唤醒的路径可以做到极短且功耗均在微安级,这个设计在低功耗便携产品里算得上是最值得优先做的改动。