1. 项目缘起与整体设计思路1.1 为什么偏偏选中这两颗芯片手头这个项目需求说起来不复杂一块便携式数据采集终端锂电池供电需要同时跑三路传感器、一路段码屏、一路低功耗无线模块还要支持USB充电和电量计。之前用分立方案搭过一版LDO加DC-DC再加充电IC板子面积大、静态功耗高、关机漏电流压不下去待机时间一直不达标。这次决定换一条路用一颗电源管理专用芯片把充电、升降压、多路输出、电量计量全包了主控那边只留一颗低功耗MCU做整机调度。选型阶段看了不少方案最后锁定PCA9422加PIC18F85K22这个组合原因很实在。PCA9422是一颗面向便携设备的电源管理单元内部集成了线性充电器、升降压转换器、多路可编程LDO、电量计和I2C控制接口等于把原来四五颗芯片的活全揽了。PIC18F85K22则是一颗带nanoWatt技术的8位MCU低功耗模式下电流能做到纳安级而且片上集成了LCD驱动、多路ADC和比较器正好匹配段码屏和传感器采集的需求。两颗芯片都支持I2C通信PCA9422负责“管电”PIC18F85K22负责“管事”分工清晰耦合度低。这里要解释一下为什么不用更常见的“MCU加独立PMIC”思路。独立PMIC通常只做电压转换充电和电量计还得另配芯片I2C地址容易冲突上电时序也要自己用GPIO去凑。PCA9422把充电、转换、计量、时序控制都做进去了配置一次寄存器就能定义好各路输出的上电顺序和默认电压MCU只需要在运行中按需微调省掉大量胶水逻辑。对于我这种板子空间紧张、又不想写复杂电源状态机的场景这种高度集成的方案省心太多。1.2 整机电源架构怎么划分整机电源架构我画了三层。第一层是输入与充电层USB的5V或者无线充电接收端的5V进来先过PCA9422的充电器模块对单节锂电做恒流恒压充电充电电流和终止电压都通过I2C配置。第二层是转换与分配层电池电压经过升降压转换器稳定到3.3V系统主轨再从这个主轨分出几路LDO分别给传感器、无线模块、段码屏背光和MCU的IO供电。第三层是监控与调度层PIC18F85K22通过I2C周期性读取PCA9422的电量计寄存器拿到电压、电流、剩余容量和充电状态再根据整机工作模式去动态调整各路LDO的开关和电压。这个划分的关键在于“谁来决定电压”。很多新手会把所有LDO都设成固定输出结果无线模块发射瞬间拉低主轨传感器读数跟着抖。我的做法是让MCU根据工作模式动态切换采集模式下传感器LDO开到3.3V、无线LDO关掉发射模式下传感器LDO降到2.8V省电、无线LDO开到3.3V并提前打开软启动。PCA9422的LDO支持通过I2C实时改电压和使能这个动态调度能力是分立方案很难低成本实现的。1.3 低功耗目标怎么拆解到每个环节整机待机目标定在80微安以下这个数字不是拍脑袋来的。锂电池容量按1200毫安时算如果待机电流80微安理论待机时间约15000小时实际考虑自放电和温度影响打个对折也有大半年足够覆盖设备仓储和运输周期。要达成这个目标得把电流拆到每个环节去抠。PCA9422在关断模式下漏电流典型值在1微安以内这是它比很多分立LDO强的地方。PIC18F85K22在休眠模式下配合看门狗定时器唤醒平均电流可以压到5微安左右。段码屏在静态显示时几乎不耗电背光关掉就行。无线模块是耗电大户待机时必须彻底断电不能只靠休眠因为休眠漏电流也有几十微安。传感器那边选的是低功耗型号单颗工作电流200微安三颗同时开就是600微安所以采集必须间歇进行不能常开。把这些数字加起来待机时MCU休眠5微安、PCA9422静态1微安、无线断电0、传感器断电0、段码屏保持显示约2微安再加上一些漏电流余量80微安的目标是合理且可达的。这个拆解过程很重要它决定了后面寄存器配置时哪些位必须关、哪些时钟必须停。2. 核心细节解析与实操要点2.1 PCA9422的寄存器配置逻辑PCA9422内部寄存器不少但真正需要频繁动的就那么几组。充电控制组负责设定充电电流、终止电压、充电使能和充电状态回读。升降压控制组设定主轨输出电压和使能。LDO控制组每一路都有独立的电压选择和使能位。电量计组提供电压、电流、剩余容量和健康状态。中断组用来上报充电完成、电量低、过温等事件。配置顺序有讲究。上电后MCU先通过I2C读一次设备ID确认通信正常然后按“先设电压再使能”的原则逐路配置。为什么不能反过来因为如果先使能再设电压输出会先跳到默认值可能超过后级器件的耐压或者造成浪涌。我一般先把所有LDO电压设到目标值再统一使能最后配置充电参数。充电参数里终止电压必须和电池规格严格匹配单节锂电通常设4.2V如果电池是高压电芯就设4.35V设错了要么充不满要么过充这个没有商量余地。充电电流的设定要算一下。假设电池容量1200毫安时按0.5C充电就是600毫安。PCA9422的充电电流是分档可调的找到最接近600毫安的那一档写进去。如果USB端口限流只有500毫安那充电电流还得再降否则会把USB拉挂。我实测时用了一个USB电流表串在输入端边充电边看实际电流确认没有超过端口能力。2.2 PIC18F85K22的低功耗配置要点PIC18F85K22的低功耗不是自动的得手动把该关的都关掉。系统时钟在休眠前要切到内部低功耗振荡器主振荡器停掉。外设时钟里ADC、比较器、LCD驱动这些如果当前不用就关掉时钟。IO口要特别注意悬空的输入脚会来回翻转造成额外功耗我的做法是把所有未使用的IO设成输出低电平或者设成输入但使能内部上拉具体看外部电路。如果外部有上拉电阻IO就设成输入如果外部悬空就设成输出低。看门狗定时器是唤醒源之一它的周期决定了MCU多久醒一次去读电量计。周期设太长电量变化响应慢设太短唤醒频繁平均功耗高。我折中设了2秒唤醒一次每次醒来只做三件事读PCA9422的电量计寄存器、判断是否需要切换模式、喂狗然后继续睡。整个唤醒处理控制在200微秒以内这样平均电流增加可以忽略。LCD驱动模块在休眠时可以保持显示这是PIC18F85K22的一个亮点。配置好LCD寄存器和偏压后进入休眠LCD波形由硬件继续产生MCU内核完全停掉。段码屏显示的内容在休眠前写好休眠期间不变。如果显示内容需要动态更新那就得定期唤醒刷新功耗会上去所以我的设计里待机界面是静态的只有按键唤醒后才刷新。2.3 I2C通信的稳定性处理两颗芯片之间靠I2C通信速率设的400kHz。PCB布线上I2C走线尽量短远离升降压转换器的电感区域因为那附近磁场变化剧烈容易耦合进通信线。上拉电阻选了2.2k这个值在400kHz下上升沿够快又不至于功耗太大。如果总线电容偏大导致波形变圆可以降到1.5k试试但别再低了否则低电平灌电流会超标。通信协议上我加了两层保护。第一层是每次读写后检查ACK如果从机没应答就重试三次三次都失败就报错并尝试复位PCA9422的通信接口。第二层是关键寄存器写入后回读校验比如设完充电电压后立刻读回来比对不一致就重写。这个回读校验在调试阶段帮我抓到了好几次时序问题因为PCA9422在某些寄存器写入后需要一点时间生效连续写太快会丢配置。注意PCA9422的部分寄存器在写入后需要等待内部状态机完成建议在关键配置之间插入1到2毫秒延时或者轮询状态位确认完成后再进行下一步。3. 实操过程与核心环节实现3.1 硬件连接与上电检查硬件上PCA9422的输入接USB的5V电池接BAT脚系统主轨从升降压输出引出。LDO输出分别接到各负载。I2C的SDA和SCL接到PIC18F85K22的对应引脚同时各接一个2.2k上拉到3.3V主轨。中断脚接到MCU的一个外部中断引脚用来响应充电完成和电量低事件。上电前先用万用表测各路输出对地阻抗确认没有短路。上电后先不装电池只插USB测升降压输出是否正常。如果输出为零先查使能位和输入电压再查I2C通信是否正常。我遇到过一回输出为零查了半天发现是I2C上拉接到了1.8V而不是3.3V导致通信电平不匹配PCA9422根本没收到配置。这个坑很隐蔽因为示波器看波形幅度是够的但逻辑电平判断出错。装上电池后再测充电电流。用USB电流表看输入电流正常应该在设定值附近。如果电流远小于设定值可能是电池电压已经接近终止电压充电进入恒压阶段这是正常的。如果电流为零查充电使能位和电池温度检测脚有些方案要求电池包内有热敏电阻没有的话得用电阻模拟一个正常温度否则充电器会认为温度异常而拒绝充电。3.2 寄存器初始化代码实现初始化代码我分成几个函数每个函数负责一组寄存器。下面这段是充电配置的示例语言用C基于常见的8位MCU开发环境。// 充电配置终止电压4.2V充电电流600mA使能充电 void PMU_ConfigCharger(void) { // 设终止电压为4.2V I2C_WriteReg(PMU_ADDR, REG_CHG_VTERM, 0x2A); // 设充电电流为600mA I2C_WriteReg(PMU_ADDR, REG_CHG_ICHRG, 0x18); // 使能充电清除其他中断标志 I2C_WriteReg(PMU_ADDR, REG_CHG_CTRL, 0x81); // 回读校验 uint8_t val I2C_ReadReg(PMU_ADDR, REG_CHG_VTERM); if(val ! 0x2A) { // 重写一次 I2C_WriteReg(PMU_ADDR, REG_CHG_VTERM, 0x2A); } }LDO配置类似每一路先设电压再使能。这里有个细节PCA9422的LDO电压档位不是线性的得查数据手册的对照表。比如要3.3V对应的档位值可能是0x1A而不是简单按比例算。我一开始按线性算设出来是3.28V虽然能用但不够准后来查表改成精确档位输出就是3.30V。升降压输出设3.3V这个也有档位表。设完后用万用表实测如果偏差超过50毫伏检查反馈脚的分压电阻是否准确。PCA9422内部有反馈网络但外部如果加了前馈电容容值不对会影响环路稳定性表现为输出电压抖动。我一般先不加前馈电容测稳了再根据需要加。3.3 低功耗模式切换流程整机有三种模式运行模式、待机模式、运输模式。运行模式下所有外设供电MCU全速跑。待机模式下传感器和无线断电MCU休眠LCD保持显示PCA9422只保留电量计和中断。运输模式下连LCD都关掉PCA9422进入最低功耗状态只保留充电检测MCU完全断电靠PCA9422的中断唤醒。切换流程用状态机实现。从运行到待机先关无线LDO延时等无线模块完成掉电再关传感器LDO然后MCU保存状态、配置唤醒源、进入休眠。从待机到运行MCU被按键或者定时器唤醒先开传感器LDO并等待稳定再开无线LDO最后恢复外设。这个顺序不能乱因为无线模块上电瞬间电流冲击大如果和传感器同时开可能把主轨拉低导致传感器复位。运输模式的进入需要长按按键组合防止误触发。进入前MCU先把LCD关掉然后给PCA9422写运输模式命令最后MCU自己断电。唤醒只能靠插USB或者按特定按键因为运输模式下MCU没电只能靠PCA9422的中断脚拉高来给MCU供电。这个电路上要设计好PCA9422的中断脚得能驱动MCU的电源使能脚或者通过一个MOS管来控制。3.4 电量计读数与校准PCA9422的电量计提供电压、电流和剩余容量。电压和电流是实时值剩余容量是基于库仑计积分算出来的。首次使用前需要做一次满充满放校准让电量计知道电池的实际容量。校准过程是充满到终止电压然后以恒定电流放电到截止电压电量计会自动记录总容量。校准后剩余容量读数就准了。实际使用中我每2秒读一次电压和电流每60秒读一次剩余容量。电压用来判断是否接近低电电流用来判断当前是充电还是放电。剩余容量用来更新LCD上的电量图标。这里有个细节电量计的电流读数有正负之分充电为正放电为负读的时候要按有符号数处理。我一开始按无符号读结果放电时读出一个巨大的正数差点触发误报警。温度对电量计有影响PCA9422内部有温度传感器可以读出来做补偿。如果设备工作在宽温环境建议把温度补偿打开。补偿参数在数据手册里有公式简单说就是低温时容量打折扣高温时略微增加。我实测在零下十度时不补偿的话剩余容量会虚高百分之十五左右补偿后就准了。4. 常见问题与排查技巧实录4.1 充电异常问题速查充电相关的问题最常遇到我整理了一个速查表。现象可能原因排查方法解决措施充电电流为零充电使能位未置位读充电控制寄存器写入使能位并回读确认充电电流为零电池温度检测异常测温度检测脚电压检查热敏电阻或模拟电阻充电电流偏小输入端口限流测USB输入电流降低充电电流设定值充电电流偏小电池接近满电测电池电压正常现象进入恒压阶段充电无法终止终止电压设错读终止电压寄存器改为电池规格对应值充电时主轨波动输入电容不足示波器看输入纹波增加输入电容或降低充电电流这个表里我特别想说的是温度检测那一条。很多电池包不带热敏电阻如果充电器配置成需要温度检测它就会一直认为温度异常。解决办法是在温度检测脚接一个固定电阻阻值对应25度时的热敏电阻值通常是10k。这样充电器就认为温度正常了。但这样做失去了温度保护量产时还是建议用带热敏电阻的电池包。4.2 I2C通信失败排查I2C通信失败的表现是读写寄存器返回错误或者读回全FF。排查步骤我按顺序来。先测上拉电压确认是3.3V不是其他电压。再测波形看上升沿是否太慢如果超过1微秒说明上拉太大或者总线电容太大。然后查地址PCA9422的I2C地址是固定的还是可配的如果是可配的确认地址脚接对了。最后查时序用逻辑分析仪抓一次完整读写看起始位、地址位、数据位、停止位是否规范。我遇到过一次通信时好时坏最后发现是I2C走线和升降压电感靠得太近电感漏磁耦合进通信线。把走线挪开两毫米就好了。这个经验告诉我电源芯片旁边的通信线一定要远离功率器件宁可绕一点也不要贴着走。还有一种情况是MCU的I2C引脚配置成了开漏但没使能内部上拉而外部上拉又没焊结果总线一直是低电平。这个用万用表一测就知道总线静态电压应该是3.3V如果是0V就是这个问题。4.3 低功耗不达标怎么抠待机电流超标是最头疼的问题因为涉及环节多。我的排查方法是逐路断电法。先把无线模块的LDO关掉看电流降多少。再把传感器LDO关掉看再降多少。然后把LCD背光关掉。最后如果还超标就把MCU设成复位状态只留PCA9422工作看PCA9422本身的静态电流是多少。有一次我测出来待机电流200微安远超80微安目标。逐路关掉后发现无线模块LDO关了之后还有80微安说明无线模块在LDO关掉后通过IO口倒灌电流。因为无线模块的IO和MCU的IO相连MCU输出高电平时电流通过无线模块内部的ESD二极管倒灌进无线模块的电源脚。解决办法是在LDO关掉之前先把相连的IO设成低电平或者高阻态。这个坑很典型凡是外设断电但IO还连着的都要考虑倒灌问题。还有一个常见问题是MCU的IO悬空。悬空的输入脚因为外部没有确定电平内部施密特触发器会来回翻转每个翻转都消耗电流。我习惯把所有未使用IO设成输出低或者设成输入但使能内部下拉。具体用哪种看外部电路如果外部有上拉就设输入如果外部悬空就设输出低。4.4 上电时序与复位问题PCA9422支持可配置的上电时序各路LDO可以按顺序启动。这个功能用好了能避免很多复位问题。比如MCU的IO电压必须在外设电压之前建立否则外设可能通过IO倒灌。我的配置是主轨先起然后MCU的IO LDO起再起传感器LDO最后起无线LDO。每路之间延时5毫秒确保前一路稳定后再起下一路。如果上电时序不对表现是MCU偶尔不启动或者外设初始化失败。用示波器同时抓各路输出的上电波形就能看出来。我建议在调试阶段把各路输出都引出测试点方便抓波形。量产时可以去掉测试点但调试阶段千万别省。复位问题还和电源的上升时间有关。如果主轨上升太慢MCU的复位电路可能在电压还没到工作范围时就释放复位导致MCU跑飞。PIC18F85K22内部有上电复位和欠压复位配置好这两个功能基本能解决。如果还不行就在复位脚加一个RC延时确保电源稳定后再释放复位。5. 实测数据与优化经验5.1 各模式功耗实测对比板子调通后我做了完整的功耗测试数据如下。工作模式主轨电流电池端电流说明运行模式采集无线发射85mA95mA无线发射瞬间峰值运行模式采集无线接收45mA52mA无线接收电流较低运行模式仅采集12mA14mA传感器和MCU工作待机模式LCD显示65uA78uA达到设计目标待机模式LCD关闭18uA22uA运输模式接近运输模式3uA5uA仅PCA9422保持充电检测从数据看待机模式78微安达到了80微安的目标。运输模式5微安非常理想。运行模式下的电流主要被无线模块吃掉所以无线发射必须控制占空比不能连续发射。我的策略是数据攒够一批再发射发射时间控制在100毫秒以内这样平均电流就下来了。5.2 动态电压调节的省电效果LDO动态调压这个功能我做了对比测试。传感器在2.8V和3.3V下都能工作但2.8V时电流从200微安降到150微安三颗传感器省150微安。无线模块在3.0V和3.3V下都能工作3.0V时发射电流从85毫安降到70毫安。虽然运行模式下这些节省看起来不多但累积起来对续航有贡献。动态调压的实现是在模式切换时顺便改LDO电压。比如从发射模式回到接收模式把无线LDO从3.3V降到3.0V。改电压之前要先确认负载能接受这个电压不能盲目降。我一般留0.2V余量标称3.3V的器件最低工作到3.0V那我就设3.1V既省电又安全。5.3 充电效率与温升充电效率我实测了一下。输入5V充电电流600毫安电池电压3.7V输出功率2.22瓦输入功率约2.9瓦效率约76%。这个效率在线性充电器里算正常因为线性充电器本质上是个可调电阻压差越大效率越低。如果输入电压能降到4.5V效率能提到85%左右。所以如果前端是无线充电接收端输出设4.5V比5V更划算。温升方面600毫安充电时PCA9422表面温度约45度环境25度温升20度。这个在可接受范围内。如果充电电流加到800毫安温升会到35度以上就要考虑加散热铜箔了。我的板子背面在PCA9422位置铺了一块铜通过过孔连到地平面散热效果不错。6. 写在最后的几点实操体会这个项目从选型到调通花了大约三周其中大部分时间花在低功耗调试和充电异常排查上。PCA9422加PIC18F85K22这个组合给我的最大感受是“集成度高但配置项多”寄存器配置对了就非常稳配错了现象很隐蔽。我的建议是调试阶段一定要把I2C通信抓出来看每个关键寄存器写入后都回读确认不要怕麻烦。另外低功耗设计是个系统工程不能只盯着MCU。外设的断电、IO的倒灌、上拉电阻的功耗这些加起来往往比MCU本身还大。我习惯在待机时用电流表逐路断开负载看哪一路贡献最大然后针对性优化。这个方法虽然笨但很有效。最后说一个容易被忽略的点电池电量计的校准。不校准的话剩余容量读数可能偏差百分之二三十用户体验很差。校准一次只要一个充放电循环但效果立竿见影。如果产品批量生产建议在产线增加一次校准工序或者用带出厂校准的电池包。