资讯动态

PCA9422与PIC18F97J94便携电源管理设计实战

发布时间:2026/10/24 3:34:18 来源:尧图企业网站定制
1. 项目缘起与整体设计思路1.1 为什么偏偏选中这两颗芯片先说说这个组合是怎么来的。项目需求很明确做一个便携式数据采集终端锂电池供电需要多路电压轨——3.3V给主控和传感器、1.8V给一颗低功耗无线模块、还有一路可调的1.2V到3.3V给模拟前端。同时要求支持USB充电、电量计、低电量报警、以及整机休眠时静态电流压到微安级。这种需求在工业手持设备、便携医疗监测、野外环境记录仪里非常典型。选型的时候我对比过几套方案。分立方案用一颗充电IC加一颗DC-DC再加几颗LDOBOM能凑出来但板子面积大、上电时序难控、休眠功耗压不下去。另一条路是用带PMIC功能的主控但那种方案往往把电源和MCU绑死灵活性差。最后落到PCA9422这颗电源管理芯片上原因有几个它集成了线性充电器、多路可配置的降压和线性稳压输出、I2C可编程、还带看门狗和复位逻辑等于把一整块电源板塞进了一颗QFN里。主控这边选PIC18F97J94看中的是它自带LCD驱动、USB模块、以及足够多的外设省掉一颗显示驱动和USB桥接芯片整体BOM反而更干净。这两颗芯片搭配的逻辑是PCA9422负责“电”的事——充电、放电、电压转换、电量监测、上电时序PIC18F97J94负责“管”的事——通过I2C读写PCA9422的寄存器根据电池状态和系统负载动态调整各路输出同时处理按键、显示、数据采集。分工清晰各司其职。1.2 整体电源架构怎么搭整个电源树是这样的USB 5V或者锂电池3.0V到4.2V作为输入源PCA9422内部自动做路径管理优先用USB供电同时给电池充电USB拔掉后无缝切到电池。芯片输出四路BUCK1固定3.3V给主控和数字传感器BUCK2可调1.8V给无线模块LDO1固定1.8V给RTC和备份域LDO2可调给模拟前端。另外还有一路VREF和一路始终开启的LDO给PCA9422自己的内部逻辑和I2C上拉。这里有个设计取舍值得说为什么BUCK2和LDO2要做成可调因为无线模块在不同工作模式下对电压和纹波的要求不一样发射时希望电压稍高保证功率接收时希望电压降低省电。模拟前端那路更是要根据传感器类型调偏置。如果做成固定输出后期换传感器就得改板子可调方案虽然软件复杂一点但硬件一次成型后续靠寄存器配置就能适配长期看更划算。上电时序也是重点。PIC18F97J94要求IO电压先于核心电压建立否则会有闩锁风险。PCA9422支持通过OTP或者寄存器配置各路输出的上电顺序和延时我把BUCK1设成第一路延时2ms后LDO1跟上再延时1ms后BUCK2和LDO2同时起来。这个顺序在调试阶段用示波器四通道同时抓过确认没有电压倒灌。1.3 通信与控制链路的设计PCA9422和PIC18F97J94之间走I2C速率400kHz。为什么不用SPI因为PCA9422只支持I2C没得选。但I2C也有好处两根线、支持多设备、有ACK机制能确认寄存器写入成功。PIC18F97J94的MSSP模块配置成I2C主机模式PCA9422的地址是0x627位写操作时最低位为0读操作时为1。控制逻辑上我把PCA9422的中断引脚接到PIC18F97J94的INT0上。PCA9422会在以下几种情况拉低中断电池电压低于阈值、充电完成、充电故障、温度超限、看门狗超时。主控收到中断后进I2C读状态寄存器判断具体事件再决定动作。这种中断加轮询的组合比纯轮询省电得多——平时主控可以睡有事才醒。注意PCA9422的I2C上拉电阻不能省而且阻值要算。400kHz速率下总线电容假设200pF上升时间要求小于300ns上拉电阻大概在2.2k到4.7k之间。我实际用4.7k示波器看上升沿约180ns留了余量。如果板子上I2C走线长或者挂的设备多电容大了就要减小阻值但太小又增加静态功耗这个平衡要实测。2. 核心细节解析与实操要点2.1 PCA9422寄存器地图怎么读PCA9422的寄存器分几大块充电控制、BUCK控制、LDO控制、ADC与电量计、中断与状态、系统配置。每块都有对应的地址范围。刚拿到芯片的时候别急着写代码先把数据手册的寄存器表打印出来用荧光笔把每个寄存器的默认值、可写位、只读位标清楚。我踩过的坑是有些位是“写1清除”的中断标志位如果你当成普通读写位去操作中断会一直挂着清不掉。几个关键寄存器我列一下实际用到的寄存器地址名称作用常用配置值0x00DEVICE_ID读芯片版本只读用于确认通信正常0x10CHG_CTRL1充电电流设置0x2A对应500mA0x11CHG_CTRL2充电电压设置0x1C对应4.2V0x20BUCK1_CTRLBUCK1输出电压0x0F对应3.3V0x21BUCK2_CTRLBUCK2输出电压0x08对应1.8V0x30LDO1_CTRLLDO1输出电压0x08对应1.8V0x31LDO2_CTRLLDO2输出电压0x0C对应2.5V0x40ADC_CTRLADC使能与通道选择0x81使能电池电压采集0x50INT_STATUS中断状态读后写1清除0x60SYS_CTRL系统配置0x03使能看门狗这张表是我调试时自己整理的数据手册上信息分散在几十页里集中列出来能省很多翻页时间。注意不同批次的芯片默认值可能有细微差异上电后先读一遍所有寄存器做基线再写配置。2.2 充电参数怎么算锂电池充电分三个阶段预充、恒流、恒压。PCA9422的预充电流默认是恒流值的10%预充阈值电压默认2.8V。恒流值由CHG_CTRL1寄存器的低6位决定步进是50mA公式是I_charge (寄存器值 1) × 50mA我要设500mA所以寄存器值 500/50 - 1 9即0x09。但实际写的时候发现0x09对应的是500mA没错可数据手册上写的是“典型值”实测用电子负载拉电流实际是487mA。这个偏差在可接受范围内因为充电电流本身不需要特别精确。恒压值由CHG_CTRL2的高5位决定步进是20mV基准是3.5VV_charge 3.5V (寄存器值 × 20mV)要4.2V寄存器值 (4.2 - 3.5) / 0.02 35即0x23。但注意这个寄存器还有低3位是充电终止电流设置默认是恒流值的10%也就是50mA。如果你用小容量电池终止电流要调小否则充不满。充电安全定时器也要设。PCA9422内部有个14位的定时器默认是8小时。我设成4小时因为500mA充2000mAh电池理论4小时留点余量。如果超时还没充满芯片会报故障并停止充电这是保护机制别嫌它烦。2.3 电量计的实现思路PCA9422内部有个10位ADC可以采集电池电压、充电电流、系统电压和温度。电量计的原理是电池电压和剩余容量之间有对应关系但锂电池的放电曲线中间很平单靠电压估算误差大。我的做法是结合电压和电流做库仑计数。具体实现每100ms读一次电池电压和放电电流电流对时间积分得到已放电量再用电压查表修正。电池电压到3.5V时对应20%电量3.3V对应5%3.0V对应0%。这个表要根据实际电池的放电曲线标定我用了三天时间做充放电循环每10%记录一次电压最后拟合出曲线。实操心得ADC的参考电压要用内部基准不要用VDD。因为VDD本身会波动用VDD做基准测出来的电池电压也跟着波动电量显示会跳。PCA9422内部有1.2V基准配置ADC_CTRL寄存器的REF位选择内部基准实测精度能到±1%。2.4 低功耗模式的配置细节整机休眠时要求静态电流小于50微安。这个目标要分解到每个器件PIC18F97J94休眠模式本身约1微安PCA9422在待机模式下约15微安剩下的就是外围电路漏电。PCA9422的待机模式配置步骤关闭BUCK2和LDO2无线模块和模拟前端不用了BUCK1切到PFM模式脉冲频率调制轻载效率高LDO1保持开启给RTC供电关闭ADC和电量计关闭看门狗设置中断只保留电池低电压检测这一套写下来大概七八个寄存器操作顺序不能乱。比如必须先关输出再切模式否则会有电压跌落导致主控复位。我一开始顺序搞反了休眠时主控偶尔会重启查了两天才定位到。3. 实操过程与核心环节实现3.1 硬件连接与上电检查焊接完板子后别急着上电。先用万用表测各路输出的对地阻抗确认没有短路。然后给USB 5V测PCA9422的VIN引脚电压是否正常再测各个输出引脚。正常情况BUCK1输出3.3V±3%BUCK2输出1.8V±3%LDO1输出1.8V±2%LDO2输出2.5V±2%。如果某路不对先查反馈电阻如果有外部分压和电感焊接。I2C通信检查用逻辑分析仪抓SCL和SDA看有没有波形。如果没有查上拉电阻和地址。PCA9422的地址由ADDR引脚决定接地是0x62接VDD是0x63。我一开始ADDR悬空通信死活不通后来查手册发现悬空是不允许的必须明确接高或接低。3.2 初始化代码怎么写PIC18F97J94的I2C初始化// I2C主机模式400kHzFosc16MHz SSP1CON1 0x28; // SSPEN1, I2C主机模式 SSP1CON2 0x00; SSP1CON3 0x00; SSP1ADD 0x27; // 400kHz: Fosc/(4*400k)-1 9? 实际算 SSP1STAT 0x80; // slew rate控制等等SSP1ADD的计算要仔细。PIC18F97J94的I2C速率公式是Fosc / (4 × (SSP1ADD 1))。Fosc是16MHz要400kHzSSP1ADD 16M/(4×400k) - 1 10 - 1 9即0x09。我上面写0x27是错的实际调试时用示波器测SCL频率调到400kHz为准。写PCA9422寄存器的函数void PCA9422_Write(uint8_t reg, uint8_t val) { I2C_Start(); I2C_WriteByte(0x62 1); // 写地址 I2C_WriteByte(reg); I2C_WriteByte(val); I2C_Stop(); __delay_ms(1); // 等芯片内部处理 }读寄存器的函数uint8_t PCA9422_Read(uint8_t reg) { uint8_t val; I2C_Start(); I2C_WriteByte(0x62 1); // 写地址 I2C_WriteByte(reg); I2C_Start(); // 重复起始 I2C_WriteByte((0x62 1) | 1); // 读地址 val I2C_ReadByte(); I2C_Stop(); return val; }注意每次写寄存器后要延时1ms因为PCA9422内部有状态机连续写太快会丢数据。我试过不延时连续写10个寄存器结果只有前3个生效后面全丢了。这个延时不是手册要求的是实测出来的经验值。3.3 上电时序的实测验证配置完上电顺序后用四通道示波器同时抓BUCK1、LDO1、BUCK2、LDO2的输出。探头用1:10的避免负载效应。触发设在BUCK1上升沿看其他三路的延时。我配置的是BUCK1先起2ms后LDO1再1ms后BUCK2和LDO2。实测BUCK1到LDO1的延时是2.1msLDO1到BUCK2是0.95ms都在允许范围内。如果时序不对检查SYS_CTRL寄存器的SEQ位和DLY位。SEQ位决定顺序DLY位决定延时步进0.5ms/1ms/2ms/4ms。我一开始DLY设成0结果所有输出同时起来主控复位了。后来改成2ms步进才正常。3.4 充电与放电切换测试USB插入时PCA9422自动切到USB供电并给电池充电。拔掉USB切到电池供电。这个切换过程要求主控不断电。实测切换时间约200微秒BUCK1输出跌落约50mV在3.3V±5%范围内主控不会复位。测试方法用电子负载模拟系统负载200mAUSB电源用可编程电源模拟插拔。示波器抓BUCK1输出同时抓USB电压。观察切换瞬间的跌落。如果跌落超过100mV检查BUCK1的输出电容是否足够。我用了两个22uF陶瓷电容并联ESR低响应快。充电电流实测设置500mA电子负载拉载实际487mA。充电效率USB 5V输入电池3.7V充电电流500mA输入电流约420mA效率约(3.7×0.5)/(5×0.42)88%。这个效率在线性充电器里算正常毕竟压差有1.3V损耗在芯片内部。3.5 电量计标定过程电量计标定是个体力活。我用了三天每天做一次完整充放电循环。步骤电池充满到4.2V静置2小时以0.2C400mA恒流放电到3.0V每下降0.1V记录一次同时记录放电时间计算每个电压点对应的剩余容量百分比最后得到一张表电池电压剩余容量4.2V100%4.0V85%3.9V70%3.8V50%3.7V30%3.6V15%3.5V8%3.4V3%3.3V1%3.0V0%这张表写进代码里用查表加线性插值。实测显示电量误差在5%以内够用了。4. 常见问题与排查技巧实录4.1 I2C通信失败怎么查这是调试阶段最常见的问题。现象是读写寄存器返回0xFF或者0x00。排查步骤用逻辑分析仪抓波形看有没有起始条件、地址、ACK如果没有波形查SCL和SDA是否被拉低短路或者从设备死锁如果有波形但没有ACK查地址是否正确、上拉电阻是否焊接如果有ACK但数据不对查时钟速率是否太快、走线是否太长我遇到过一次SDA被拉低不放原因是PCA9422在上电过程中如果VIN上升太慢内部逻辑会卡住。解决办法是在VIN和地之间加一个10uF电容保证上电斜率。这个坑数据手册上没写是实测出来的。4.2 充电电流上不去设置500mA但实际只有100mA。可能原因输入电源限流了。USB口如果只给500mA充电电流加系统负载超过500mA输入电压会被拉低PCA9422自动降充电电流。解决办法是用能提供1A的电源或者降低系统负载。电池电压太低处于预充阶段。预充电流默认是恒流的10%也就是50mA。等电池电压升到2.8V以上才进恒流。这个不是故障是正常保护。温度超限。PCA9422内部有温度检测超过85度会降电流。摸一下芯片烫不烫烫的话检查散热焊盘是否焊接良好。4.3 休眠电流偏大目标50微安实测200微安。排查先断开主控只留PCA9422测电流。如果还是大问题在PCA9422配置。检查是否有输出没关。用万用表测各路输出如果有电压说明对应通道没关。检查I2C上拉电阻。4.7k上拉到3.3V如果总线一直低会有700微安电流。正常空闲时总线是高不耗电。检查ADC是否关闭。ADC使能时约50微安。检查看门狗是否关闭。看门狗约10微安。我最后定位到是LDO2没关因为寄存器写漏了一位。补上后电流降到45微安。4.4 常见问题速查表现象可能原因排查方法解决措施I2C无响应地址错误/上拉缺失逻辑分析仪抓波形确认地址补上拉充电电流小输入限流/预充/过温测输入电压摸芯片温度换电源等预充结束查散热休眠电流大输出未关/ADC未关逐路测电压读寄存器补写寄存器关外设上电复位时序错误/电压跌落示波器抓时序调整SEQ和DLY电量跳变基准不稳/未滤波读ADC值用内部基准加滤波切换掉电输出电容不足抓切换波形加大电容选低ESR4.5 几个容易忽略的细节第一PCA9422的散热焊盘必须接地而且要多打几个过孔。我第一版板子只打了4个过孔充电时芯片温度到90度降电流了。第二版打了9个过孔温度降到65度。第二BUCK电感的选型。饱和电流要大于最大输出电流的1.5倍。BUCK1最大500mA电感选1A饱和电流的。DCR要小否则效率低。我用的是4.7uH、1A、DCR 80毫欧的。第三输出电容的ESR。BUCK输出纹波和ESR成正比。用X5R或X7R陶瓷电容ESR几毫欧纹波能压到10mV以内。如果用钽电容ESR几百毫欧纹波就大了。第四I2C走线要等长尽量短远离电感和开关节点。我有一版把I2C走线从电感下面穿过通信误码率很高后来改到板子另一层就好了。5. 写在最后的一些个人体会这个项目从选型到量产折腾了大概四个月PCA9422加PIC18F97J94的组合整体是靠谱的但前提是把寄存器配置和上电时序吃透。我最大的体会是电源管理芯片的调试示波器和逻辑分析仪比代码重要。很多问题看波形一眼就明白光看代码想破头也找不到。另外电量计的标定别偷懒。用默认的电压查表法误差能到20%用户看到电量从30%直接跳到10%会骂人。花三天做一次完整标定后面省心得多。最后分享一个小技巧PCA9422的所有配置寄存器上电后先读一遍存到数组里改的时候基于数组改最后一次性写回去。这样避免读-改-写的时序问题也方便做配置版本管理。我后来把配置数组存在PIC18F97J94的EEPROM里换电池或者换传感器的时候改EEPROM就行不用重新编译代码。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑