首页 / 资讯中心 / 文章详情

基于PCA9422与PIC18LF4610的低功耗电源管理方案设计与实战

基于PCA9422与PIC18LF4610的低功耗电源管理方案设计与实战 ★ FEATURED ARTICLE
做低功耗硬件这些年电源管理一直是最容易翻车、也最考验设计的环节。最近在做一个可穿戴设备项目时我用 PCA9422 做前端电源管理芯片搭配 PIC18LF4610 做主控制器完整实现了一套可动态调压、多时序控制、具备状态监测能力的电源管理系统。本文把这套方案从选型思路、硬件电路到低功耗策略和调试实战全部拆开讲一遍适合正在做电池供电产品、或者想了解 PMIC 加 MCU 如何协作的开发者参考。1. 项目背景与整体方案选型1.1 为什么选择 PCA9422 加 PIC18LF4610 这套组合先说结论这套组合的核心价值在于把多路电源输出和灵活控制策略分开处理各司其职。PCA9422 负责把所有电压转换工作扛下来PIC18LF4610 负责大脑和策略两者通过 I2C 通信协作比用一堆分立 LDO 加逻辑控制靠谱得多。可穿戴设备、物联网节点这类产品有个共同点体积受限、电池容量小、对休眠功耗极度敏感。常见需求往往是同时供应多路电压比如 MCU 的 3.3V、传感器的 1.8V、无线模块的 3.0V、还有内部的 1.2V 逻辑电压。如果全部用分立 LDO每一路都需要独立的使能控制、滤波电容、分压配置PCB 面积大不说各路之间的上电时序协调只能靠硬件设计敲死后续想调整一个电压值或者改时序就得改板子。而使用可配置 PMIC 后这一切都变成了寄存器里的数值产品和软件人员可以随时调整硬件无需改动。当初选型时我对比过三种方案全分立 LDO 方案、PMIC 加 MCU 方案、以及集成 PMIC 的无线 SoC 方案。全分立方案成本低但灵活性差集成 PMIC 的 SoC 虽然省事但 MCU 部分不是我想要的架构引脚和外设也不匹配强制迁移会影响整个项目进度。最终确定 PCA9422 搭配 PIC18LF4610 的原因有三点第一PCA9422 集成了多路降压转换器和 LDO并且全部支持 I2C 配置输出电压、软启动时间、上下电时序都可以编程。这一点对后期调试极其重要不用每次改电压都重新做一版 PCB。第二PIC18LF4610 本身是低电压版本工作电压范围宽休眠电流可以做到微安级别官方数据手册标称典型休眠电流能到几百纳安量级。虽然实际板上不可能那么理想但至少底子好不会拖累整个电源系统的待机功耗。第三PIC18LF4610 内置 MSSP 模块支持 I2C 主模式10 位 ADC 足够采集电池电压和闭环反馈内部振荡器还能省掉外部晶振。这些外设刚好覆盖电源管理需要的全部功能不需要额外扩展芯片。方案类型灵活性板级面积静态功耗控制调试友好度成本全分立LDO低大中等低低PMIC MCU高中优秀高中集成PMIC的SoC中小良好中中高1.2 系统电源域划分与整体架构整个系统的电源输入是一节锂离子电池工作电压范围大概在 3.0V 到 4.2V 之间极端情况下会到 2.7V 左右。围绕这个平台我把负载划分成了五个电源域VDD_MCU3.3V供 PIC18LF4610 及少量逻辑电路VDD_SENSOR_I/O1.8V供传感器数字接口VDD_ANALOG3.0V供模拟前端和运放VDD_CORE1.2V供低电压数字核心如果有协处理器或专用 ASICVDD_RADIO3.3V供无线模块需要独立可控PCA9422 内部资源恰好覆盖这些需求两路高效 Buck 转换器加上两路 LDO。Buck1 输出 3.3V 给 MCU 域Buck2 输出 1.8V 给传感器域LDO1 输出 1.2V 给核心域LDO2 输出 3.0V 给模拟域而无线模块的 3.3V 则从 Buck1 后面加一个负载开关取电。之所以给无线模块单独加负载开关是因为它的峰值电流很大直接挂同一条 Buck 上会影响其他负载的电压稳定性加一级负载开关之后关断时真正做到了物理断电不会有 PMIC 输出缓存电容继续供电的问题。PIC18LF4610 在整个架构里的角色不只是配置 PMIC 一次就够了而是作为常驻电源管家存在。它通过 ADC 持续采集电池电压、监控各电源域状态根据当前运行模式实时调整 PMIC 输出电压和使能状态。这套协作关系让整个设备的电源永远处于够用但不多给的状态。2. 硬件电路设计与关键参数推算2.1 PCA9422 外围电路与被动器件选型PCA9422 这类 PMIC 的性能发挥很大程度取决于外围被动器件的选型。很多开发者拿到 PMIC 之后习惯直接用参考设计里的参数这没错但有几个细节值得单独讲。输入电容方面我在电池输入端并联了一颗 10µF 陶瓷电容和一颗 0.1µF 高频电容。10µF 负责蓄能0.1µF 负责滤除电池走线上的高频噪声。陶瓷电容必须选 X5R 或 X7R 介质千万别用 Y5V它的容值随温度和直流偏压变化太离谱。这里有个实际经验10µF 的 X5R 电容在 3.6V 偏压下实际有效容值可能只剩 40% 到 60%所以输入侧并联两颗 10µF 也不过分当然后期实测纹波如果已经满足要求可以省掉一颗。输出电容同样有讲究。Buck 输出我用了 22µF 焊盘尺寸为 0603 的 MLCC放在靠近输出引脚的位置。电感选了 2.2µH 的功率电感饱和电流至少要大于最大负载电流的 1.5 到 2 倍。计算功率电感感值的经验公式是 V L × ΔI/Δt其中 ΔI 通常取最大负载电流的 20% 到 40%在开关频率确定的情况下反推 L 即可。举个例子开关频率 2MHz、最大负载电流 500mA、允许纹波电流 120mA、Buck 输入 3.6V、输出 1.8V那么导通时间大约为 VOUT / (VIN × f) ≈ 250ns需要的电感量大概是 (VIN - VOUT) × ton / ΔI ≈ 1.8V × 250ns / 120mA ≈ 3.75µH。实际我会选 2.2µH 或 3.3µH留一点余量但不要过大感值过大会拖慢瞬态响应。各输出引脚旁边一定要放滤波电容组合我习惯用一个较大的储能用和一个较小的去耦用搭配比例大概是 10:1也就是 22µF 配 0.1µF。除非数据手册有明确要求否则不建议全部堆大电容功率路径的瞬态响应会被压慢。还有两处容易被忽略一是 PMIC 的 I2C 引脚 SCL 和 SDA 必须要加上拉到 VIO 供电轨上拉电阻我选 4.7kΩ当总线上挂载的设备少、走线短时这个阻值足够保证上升沿速度二是使能引脚和复位引脚不能悬空即使软件配置里写了默认使能硬件上还是需要按 PMIC 数据手册要求拉好或者接 MCU 的 GPIO 控制悬空引脚在电磁干扰下可能给出误触发。2.2 PIC18LF4610 与 PCA9422 的接口设计细节PIC18LF4610 与 PCA9422 之间的物理连接其实非常简单核心只有三组信号I2C 的 SCL 和 SDA、PCA9422 的中断输出到 MCU 的 INT 引脚、以及若干使能控制线。I2C 接口需要注意电平匹配。PCA9422 的 I2C 引脚电平由 VIO 引脚决定通常 VIO 接系统的主逻辑电压 3.3V与 PIC18LF4610 的 I/O 电平一致。如果 VIO 接的是 1.8V而 MCU 是 3.3V 供电那必须在 SCL、SDA 中间串接电平转换。实际项目中我没用专用的电平转换芯片而是用两颗三极管搭的双向电平转换器成本低、速度也够 400kHz 使用但如果大家不想折腾还是直接上转换芯片稳妥。ADC 采集电池电压时我使用了两个电阻对电池正极做分压将最高 4.2V 分到约 ADC 量程的三分之二处留出裕量。阻值选择上要特别小心分压电阻如果太小分压支路本身会产生微安级别的漏电流在休眠时是不可接受的如果太大又会和 ADC 的输入采样阻抗叠加导致采样值偏低。我最终选择了 1MΩ 加 510kΩ 的组合等效源阻抗约 340kΩ配合 PIC18LF4610 的 ADC 采样时间设置成 20µs 以上实测误差控制在 10mV 以内。为了让休眠时彻底断开分压支路M CU 就用一颗 I/O 引脚控制分压电阻的供电进入睡眠之前把引脚拉低分压支路零电流。这个小技巧在低功耗设备里非常实用。PCA9422 的中断输出引脚我接在 PIC18LF4610 的外部中断输入上。PMIC 检测到输入低压、过温、输出过流或者某个电压跌出预设窗口时会拉低中断引脚。MCU 可以从深度睡眠中被这个下降沿唤醒再通过 I2C 读取状态寄存器判断具体原因。这套机制让系统对外部异常有了实时反应能力而不是靠 MCU 周期性轮询。2.3 PCB 布局地与环路处理经验电源类电路 PCB 布局的核心矛盾永远只有一条开关环路要尽量小但功率器件散热又要留空间。PCA9422 的 Buck 开关节点是整块板子上最脏的地方高频方波信号在开关节点上跳动如果把布板处理不好EMI 问题会伴随整个开发周期。我的做法是先确定开关环路的最小区域。从输出电感、开关节点、续流路径、输出电容形成的地环路面积必须压缩到最小。具体来说电感放在 PMIC 输出引脚附近输出电容紧贴电感输出端地路径通过过孔直接落入底层完整地平面。PCB 的第二层整层做地不在开关区域开槽也没有其他信号线跨过开关节点下方。底层对应的电感正下方区域我不铺地不布线防止涡流加热和寄生耦合。模拟信号与功率地之间我并没有采用激进的分割地平面做法而是先统一铺地再把低噪声的 MCU 和 ADC 参考区域通过一个磁珠单点连接到主地平面。过度分割地平面会迫使回流信号绕路反而增加噪声。对于电源管理板这种功率和模拟混合的场景完整地平面加局部滤波的方式一直是更稳妥的选择。I2C 走线我把它放在背对电感的位置尽量短且等长总线上的上拉电阻靠近 PMIC 的 VIO 引脚放置。板上预留了四个测试点电池电压、PCA9422 的输出 A、输出 B、以及中断信号线这四个测试点在后续调试中几乎天天用到强烈建议抄作业先预留下来。3. 驱动开发与电源管理策略落地3.1 I2C 初始化与 PMIC 寄存器配置流程PCA9422 的所有核心动作包括输出电压设定、时序使能、状态查询都通过寄存器操作完成。PIC18LF4610 平时把 PMIC 配置代码放在上电初始化阶段流程相当固定我贴一段关键代码供参考。void pmic_init(void) { uint8_t status; // 1. 等待 PMIC 内部 LDO 和基准源稳定 __delay_ms(5); // 2. 读设备 ID确认 I2C 通信链路正常 while (pmic_read_reg(PMIC_REG_ID, status) ! PMIC_OK) { // 连续失败则点亮错误灯提示不继续往下走 } // 3. 配置 BUCK1 输出 3.3V pmic_write_reg(PMIC_REG_BUCK1_VSET, 0x1A); // 4. 配置 BUCK2 输出 1.8V pmic_write_reg(PMIC_REG_BUCK2_VSET, 0x0C); // 5. 配置 LDO1 输出 1.2V pmic_write_reg(PMIC_REG_LDO1_VSET, 0x05); // 6. 配置 LDO2 输出 3.0V pmic_write_reg(PMIC_REG_LDO2_VSET, 0x16); // 7. 写入使能寄存器按 BUCK1 - BUCK2 - LDO1 - LDO2 顺序开启 pmic_write_reg(PMIC_REG_ENABLE, 0x1E); // 8. 回读校验确保每路输出电压寄存器与写入值一致 for (uint8_t i 0; i 4; i) { pmic_read_reg(PMIC_REG_BUCK1_VSET (i * 2), status); if (status ! expected_values[i]) { // 记录错误上报异常 } } }这段代码里有两个细节值得展开。第一上电后延迟 5ms 才访问 PMIC是为了等 PMIC 内部的掉电复位释放和基准电压稳定。如果 MCU 跑得比 PMIC 快在 PMIC 还没准备好时就发起 I2C 访问大概率拿到的是垃圾数据甚至导致后续配置失败。实际调试中我见过有人把这段延时砍掉结果系统偶发性起不来查了很久才定位到是时序竞争。第二每次写完寄存器之后必须回读校验。I2C 通信是半双工的虽然写操作的 ACK 能证明从机收到了字节但不能保证从机把数据正确存进了寄存器。回读校验会把潜在问题在上电阶段暴露出来而不是让设备在客户现场莫名其妙地出现电压异常。3.2 多模式电源状态机设计电源管理不是一个静止的过程系统会在运行、待机、深度睡眠、关机等状态之间切换每切换一次PMIC 各路输出的组合和价值都会变化。我把这套逻辑抽象成了一张状态机表每个状态对应一组明确的 PMIC 寄存器配置。电源模式BUCK1 3.3VBUCK2 1.8VLDO1 1.2VLDO2 3.0V无线模块典型用途RUN开开开开开正常工作LIGHT_SLEEP开开关开关待机等待按键DEEP_SLEEP开关关关关传感器休眠SHUTDOWN关关关关关完全关机状态切换动作里最容易出错的是从 RUN 切到 DEEP_SLEEP 时忘了关无线模块。因为无线模块的供电不是在 PMIC 的直接输出上而是经过负载开关二次分配的所以状态切换代码需要额外一行单独控制 GPIO 去断开负载开关。这种跨模块的依赖关系只用一张 PMIC 配置表看不出来需要在代码层面明确每个外设的电源来源。状态切换时我遵循一个原则关闭电源时按外设、核心、总线顺序来打开电源时按总线、核心、外设顺序来。这个原则保证任意时刻都不会出现核心还在运行但外设已经被断电或者外设已经上电但核心还没就绪这种中间态。void power_set_mode(uint8_t mode) { switch (mode) { case POWER_MODE_DEEP_SLEEP: // 先断开外设电源 gpio_radio_power_off(); // 再关 PMIC 中的 LDO pmic_write_reg(PMIC_REG_ENABLE, 0x03); // 最后 MCU 进入 SLEEP enter_sleep(); break; case POWER_MODE_RUN: // 先恢复 PMIC 电源 pmic_write_reg(PMIC_REG_ENABLE, 0x1E); // 再给外设上电 gpio_radio_power_on(); break; } }中断唤醒路径我选择让 PCA9422 的电源正常中断以及外部按键都接到同一颗外部中断引脚。在 DEEP_SLEEP 模式里PMIC 的 BUCK1 仍在工作保证 MCU 的 RTCC 定时器和 IO 中断可用。MCU 被某个中断唤醒后先读中断标志、再读 PMIC 状态寄存器确认电源切换到哪一个状态然后调用对应的模式恢复函数。这套机制实测稳定没有出现过唤醒后电压不对导致系统卡死的情况。3.3 动态调压与系统低功耗的整体配合PCA9422 支持在运行状态下通过 I2C 改写输出电压设定值这就意味着系统可以在负载降低的时候主动把电压调低减少损耗。动态调压我主要用在了两个场景。第一个场景是 MCU 内核电压。PIC18LF4610 在 32MHz 全速运行时的最低工作电压和运行在低频时的最低工作电压往往不同利用这个特性当系统从全速运算状态切换到低功耗等待任务时我先通过 I2C 把该路电压从 3.3V 降到 2.8V再让 MCU 切到低频模式。表面上看这个操作节省的功率有限但如果设备一天里有十几个小时处于这种半休眠状态累积的能耗差异仍然可观。第二个场景是无线模块的发射功率等级。无线模块不发射时不需要那么高的供电电压通过 DVS 降 0.3V 到 0.5V能让整个射频前端的静态电流下降不少。关键是降电压之前必须先确认无线模块厂商保证的最低工作电压低于这个值模块会出现无法解释的通信异常排查起来极难。动态调压过程中有个细节很关键改电压设定寄存器时负载不能处在电流剧变的状态。比如无线模块正在发射时去调电压哪怕只是下调 0.3V也可能触发瞬间欠压复位。所以我会在调压前通过系统内标志位锁住无线模块的发射任务调压完成后才解除锁定。代码里就是加一个互斥量简单但有效。低功耗配合方面控制器本身的功耗同样不能忽视。PIC18LF4610 在进入深度睡眠前除了停止外设时钟我还会把不使用的 I/O 引脚统一配置为数字输出并输出低电平防止引脚悬空产生灌电流路径。实测发现很多低功耗板子的休眠电流偏大问题都源自于某些悬空 I/O 引脚通过内部保护二极管产生了无法察觉的泄漏路径逐一排查非常痛苦但一开始就养成休眠前整理引脚状态的习惯能少踩很多坑。4. 调试过程与常见问题排查实录4.1 上电时序异常导致系统死锁样机第一次上电就遇到了问题接上电池后电流表显示约 200mA但 MCU 完全没有运行用示波器抓 PCA9422 各路输出波形时发现BUCK2 的 1.8V 输出比 BUCK1 的 3.3V 提前了大约 1.4ms 上电。问题在于1.8V 供的是传感器的 I/O 电平传感器芯片在 3.3V 主控尚未就绪时提前上电内部寄生的 ESD 二极管会对主控方向正向导通把主控的 3.3V 电源轨钳位在 1.8V 加一个二极管压降左右导致主控始终处在欠压状态无法启动。排查过程比较顺利因为我已经预留了各路输出的测试点示波器四通道同时抓到各路输出波形一眼就看出时序问题。根因是 PMIC 的默认时序配置是从低电压到高电压依次开启而我的系统实际上要求先开启主控电压再逐步开启外围电压。解决方法是在 PMIC 初始化代码里显式写入时序配置寄存器将 BUCK1 设为最先启动BUCK2 和 LDO 依次延迟启动各间隔 500µs 左右。另外把 BUCK1 的输出电容稍微加大到 47µF利用电容充电的天然延迟让后级器件上电更平缓。这次的教训是任何 PMIC 的默认时序都不能直接当作系统时序来信任PMIC 的默认配置只是为了保证它自身的启动安全不一定适配你的外设。拿到样机后第一件事就是要对照全部负载芯片的数据手册整理一份各路电源的上电顺序矩阵然后把这个矩阵落实为 PMIC 的初始配置。4.2 I2C 总线偶发通信失败第二块难啃的骨头是 I2C 通信偶发失败。系统能正常启动但在运行过程中MCU 偶尔读到的 PMIC 寄存器值是全 FF或者写操作直接收到 NACK一天大概会复现四五次。用示波器抓 SCL 和 SDA 波形时发现SCL 和 SDA 的信号上升沿非常缓高电平建立时间明显变长接近 I2C 快速模式 300ns 的上升沿极限。这是因为我在调试阶段为了临时挂一个传感器模块用了较长的杜邦线把 I2C 总线延长了约 15cm总线电容大幅增加再加上原先的上拉电阻是 10kΩRC 常数过大上升沿严重劣化。理解一下物理本质I2C 的上拉电阻和总线寄生电容组成一阶 RC 电路边沿时间大约等于上拉电阻乘以总线电容。10kΩ 乘以 150pF时间常数约 1.5µs这已经超出快速模式的要求了。解决措施分两步走。硬件上我把上拉电阻从 10kΩ 换成 4.7kΩ同时把临时杜邦线拆掉恢复 PCB 走线直连。软件上我把 I2C 时钟从 400kHz 降到 100kHz 重新跑了一整天压力测试问题没有再复现。之后又试着恢复 400kHz发现依然稳定说明硬件改动才是治本。给后人的建议是I2C 在低速短距离时非常皮实但一旦速度和距离上去就必须把上拉电阻、总线电容、上升沿时间放在一起计算而不是凭感觉差不多就行。4.3 深度休眠电流偏大逐路排查定位深度休眠模式标称要做到整机 20µA 以内第一次实测却是 180µA 左右超出预期八倍。这个量级的差距不是某个器件数据手册写错而是软件状态和硬件状态没有对齐。排查思路是从总到分、逐路断开。我先把万用表串在电池输入端测总电流然后依次用杜邦线断开无线模块供电、模拟前级供电、传感器供电。断到传感器供电时电流从 180µA 降到了 30µA定位到了传感器域。继续深入发现是状态机切到 DEEP_SLEEP 时只关闭了 PMIC 的 BUCK2 使能寄存器但传感器芯片的某个状态引脚还接着外部上拉MCU 进入休眠之后这个上拉电阻形成了持续的灌电流路径。这个问题极具代表性PMIC 关了电源不代表整个路径上就不耗电了。任何从 VCC 到 GND 之间存在的电阻性通路即使不在 PMIC 输出范围内都会贡献待机电流。处理方案是梳理系统里所有由电池电压直供或者受控电压域供电的负载确保它们在深度休眠时供应侧和信号侧同时断开不能仅仅靠 PMIC 的一个使能位。我还养成了一个习惯每次低功耗优化之后都用热成像仪照着板子看一圈。局部发热明显的地方往往就是漏电路径所在。热成像不是必需设备但它能把逐路断开这种耗时工作变得直观很多。4.4 电池电量测量不准跳动严重最后说一个电量采集的问题。PIC18LF4610 用 ADC 读电池分压后计算出的电压值在设备运行期间波动很厉害同一秒内最大最小值能差 0.2V 左右这种跳变直接导致电量百分比在屏幕上一格一格地乱跳用户体验非常差。波动来源主要有两个。一个是高频噪声Buck 开关噪声和无线发射电流突变都会在 ADC 采样时刻叠加干扰。另一个是负载突变产生的电池内阻压降电池内阻乘以大电流负载在采样瞬间被 ADC 捕捉到导致读数骤降。处理手段我用了三重组合。首先是硬件层面在 ADC 采样引脚并联一颗 100nF 的稳压电容并在采样引脚和分压电阻之间串联一颗 1kΩ 电阻构成低通滤波。其次是软件层面连续采样 16 次去掉最大值和最小值后取平均等效成一个简易的均值滤波器。最后是策略层面把电压换算电量的算法从单点映射改为迟滞判断平滑滤波每次电量变化需要连续多次采样都越限才更新显示值并且限制单次更新幅度。这三招加在一起最终把电量显示的稳定性做到了体感层面几乎不跳变。在实际项目中电量显示要的不是瞬时精度而是稳定的心理预期这是做产品和高精度仪表之间的思维差异。5. 实测数据与后续优化方向5.1 各模式整机功耗实测结果整套系统稳定运行后我重新测量了各个模式下的整机电流。测试条件为 3.6V 锂电池供电、无线模块保持关闭但使能引脚处于待命状态、MCU 外部中断使能。电源模式整机电流PMIC 静态贡献备注RUN 全速约 12mA约 15µA数据采集加无线发射LIGHT_SLEEP约 80µA约 8µA传感器保持供电DEEP_SLEEP约 15µA约 5µA仅 MCU 和 PMIC 维持SHUTDOWN约 2µA约 2µA整个系统物理断开最深的体会是整机功耗的瓶颈很少在 PMIC 本身更多在系统里没有被充分管理的负载和路径。PCA9422 的静态电流本身就很小它能做的是给每个外设一扇独立的门但门是否关紧、门外有没有漏电旁路取决于系统工程师的梳理能力。5.2 基于这套架构还能继续扩展的方向这套 PMIC 加 MCU 的电源架构后续有几个很自然的扩展方向。加电量计。PCA9422 负责电源分配PIC18LF4610 负责控制策略电量计功能完全可以外挂一颗支持库仑计法的电量芯片通过 I2C 接入现有总线。这样的话电量估算不依赖电压查表精度和线性度会大幅提升尤其是低电量区间。加故障日志。利用 PCA9422 的中断引脚和状态寄存器MCU 可以在每次异常事件发生时记录时间戳和故障类型存入 Flash 的专用区域。设备返修时通过调试接口读出日志基本能还原故障发生前的电源状态这对消费类产品售后分析来说价值极高。做成多节电池输入的平台。当前方案只针对单节锂电池如果把电池前端换成一棵支持宽压输入的充电管理加升降压转换器这套 PCA9422 加 PIC18LF4610 的架构完全可以向上扩展到平板、便携仪器等对功耗不那么极端的场景。最后再分享一个实操小技巧调试任何 PMIC 系统建议第一步先做把所有输出设置成最高电压并全部使能的裸跑测试用电子负载逐路拉电流确认每条电源轨都能在额定负载下稳定输出。只有先把功率路径调扎实了再去优化时序和低功耗策略才有效。电源系统的问题往往环环相扣抓住最底层的功率完整性后面所有上层策略才有立足之地。
阅读完成 · 觉得有帮助?
咨询建站