我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

低功耗电源管理实战:PMIC与MCU协同设计多路电压轨

低功耗电源管理实战:PMIC与MCU协同设计多路电压轨 前段时间在做一款用单节锂电池供电的便携环境监测节点最开始电源部分图省事直接一组 LDO 把电池电压降到 3.3V 就完事。结果等整机联调时才发现传感器需要 1.8V 低噪声电源无线模块要 3.3V 且瞬态电流大核心逻辑又想要独立供电板子上光稳压器就堆了四五个休眠电流还一直压不下去。后来整套电源方案重新推倒换成了 PCA9422 加 PIC18LF46K42 的组合才把多路电源、动态调压、低功耗休眠、过压欠压保护这几件事真正收口到一套方案里。这篇文章会把这套方案的器件分工、硬件设计、软件流程和踩坑记录从头到尾整理出来适合正在做低功耗采集节点、便携仪表、无线传感器这类项目的朋友直接参考。PCA9422 负责把电池电压高效转成系统需要的多路低压轨PIC18LF46K42 则通过 I2C 动态调整输出、监测电压电流、带着整套系统按需休眠和唤醒。两个芯片一个管“力气活”一个管“调度”配合起来正好覆盖了完整电源管理要解决的几乎全部问题。1. 为什么用 PMIC 加 MCU 双芯方案而不是一堆 LDO1.1 三个绕不开的电源痛点先说说最初那版设计为什么行不通。单节锂电池的电压范围是 3.0V 到 4.2V而系统里的无线模块、传感器、数字核心、模拟接口各要各的电压。如果全用 LDO3.3V 轨从 4.0V 降下来效率只有 82% 左右看着还行但 1.2V 轨从同样电压往下降效率就只剩下 30%接下来全部变成芯片上的热量。电池容量小的设备这种热损耗会直接反映在续航上几十毫安电流持续发热机身都能感觉到温度。第二个问题是静态电流。LDO 本身要维持内部基准和反馈环路静态电流通常在微安到几十微安之间。单个看不大但多个 LDO 叠加加上分压电阻、使能脚上拉、电源指示 LED整机休眠电流很容易做到 200 微安以上。对于用 500mAh 锂电池的设备这个底的漏电速度相当可观放一个月电池就没了一半。而 PMIC 本身针对电池供电优化过待机功耗控制得更好配合 MCU 的休眠模式可以把平台静态电流压到 10 微安级别。第三个问题更隐蔽多路电源的上电时序和异常保护。有些传感器对供电顺序敏感先给 I/O 供电、后给核心供电可能导致闩锁或者状态混乱。分立方案常见的做法是用 RC 延时、用负载开关依次打开但这套做法既不精确也不可靠温度变化之后延时漂移很严重。PCA9422 这种集成 PMIC 本身有软启动、限流、过温保护各路输出的打开顺序又可以由 MCU 通过软件控制比纯硬件搭出来的时序电路灵活太多。1.2 为什么具体选了这两个型号PCA9422 这边最大的价值就是把多路电源集成到了一颗芯片里。它包含两路可编程的同步降压转换器和一路 LDO输出电压可以通过 I2C 寄存器配置而不是靠更换反馈电阻来改电压。这一点对动态电压调节特别重要正常工作时让核心电压跑在 1.2V进入待机前降到 0.9V唤醒后再升回来整个过程不需要动任何硬件。要是用分立 LDO改电压就得换电阻或者额外加 DAC 控制反馈端复杂度完全不在一个量级。PIC18LF46K42 这颗 8 位 MCU很多人一开始会怀疑性能不够。但做电源管理调度它其实是更合适的选择。首先它工作电压范围宽1.8V 到 3.6V 都能跑和 PMIC 输出配合灵活。其次它的外设集成度很高内部带了运算放大器、可配置逻辑单元、带计算功能的 ADC2、多个定时器和比较器。这意味着电压电流采样、阈值比较、硬件保护这些功能不需要外扩芯片也不占用过多的 CPU 时间。相比 32 位 MCU8 位机在这个场景还有一个天然优势启动快、功耗低、外设独立性强。系统从休眠唤醒到进入工作状态几十微秒就能完成而很多 32 位平台从时钟稳定到外设初始化经常要花上毫秒级时间。对需要频繁“采样、发送、休眠”的物联网节点来说这个差距会实实在在体现在平均功耗上。选择 PIC18LF46K42本质上不是“算力不够硬凑”而是“外设够用、功耗更低、响应更快”的合理取舍。2. 硬件搭建前必须想清楚的事2.1 电压轨怎么划分先别急着画原理图把系统里每个模块需要的电压和最大电流列一张表这一步省掉后面调试会非常痛苦。我当时参考的是一个典型的环境监测节点需求电源轨电压主要负载峰值电流备注Buck11.2VMCU 核心逻辑、数字传感器50mA可动态调压休眠前降到 0.9VBuck23.3V无线模块、外部传感器120mA瞬态电流大需要足够输出电容LDO1.8V模拟前端、参考电压20mA低噪声要求靠近负载摆放这张表不是随手拍的它直接决定了 PMIC 每个通道的配置方向和功率余量。比如 1.2V 这一路如果用 LDO 从 3.7V 典型电压降下来效率只有 32%而用 Buck 可以达到 85% 以上。系统总功耗 150mW 左右时LDO 方案会白白多烧 30mW 的热对电池供电设备来说这是完全不能接受的。还要考虑 PMIC 的输入能力。单节锂电池满电 4.2V截止电压 3.0VPCA9422 的输入范围要能覆盖整个区间。另外Buck2 输出 3.3V 时输入电压低于 3.3V 之后Buck 会进入 100% 占空比直通状态输出电压会跟随电池电压下降。所以如果对 3.3V 轨有严格精度要求要么加一个升压电路要么接受电池低电量时 3.3V 轨同步下降并在软件里做欠压预警。2.2 引脚连接与 I2C 信号完整性PCA9422 和 PIC18LF46K42 之间的连接核心就两件事电源和 I2C。电源连接上每一路输出的去耦电容要按手册要求放通常输入侧放 1uF 加 0.1uF输出侧放 4.7uF 或 10uF具体值参考芯片手册推荐。电感的选择也不能随便感值、饱和电流、直流电阻三个参数都要看。感值选太大会导致瞬态响应慢选太小又在重载时容易饱和电流一大输出电压就开始掉。我这次用的是 2.2uH 的电感饱和电流按 1.2 倍最大负载电流留了余量。I2C 连接上PCA9422 的 SCL 和 SDA 是开漏结构必须接上拉电阻。上拉值的选取要看总线电容和通信速率。总线上挂着两颗芯片、走线又不长的情况下2.2k 到 4.7k 是比较稳妥的区间。阻值太小会增加低电平拉下去的灌电流阻值太大又会让信号上升沿变缓高速模式下容易采样出错。我当时先按 4.7k 配实测 400kHz 模式下波形上升沿勉强能用后来改成 2.2k 才留出足够裕量。还有一点很容易忽略PMIC 的 I2C 引脚电平范围。如果 PMIC 的 I/O 只支持 1.8V 逻辑而 MCU 由 3.3V 供电直接用 3.3V 信号去驱动可能会永久损坏 PMIC。这个一定要在选型阶段确认一旦需要电平转换方案复杂度会上升很多。我这边确认过 PMIC 的 I2C 引脚兼容 1.8V 到 3.3V所以直接共用一个 3.3V 电平域。PIC18LF46K42 的 I2C 引脚不是固定死的K42 系列带有外设引脚选择功能SCL 和 SDA 可以通过配置寄存器映射到不同的引脚。这个功能很实用可以把 I2C 从默认引脚挪开避开和 PWM、ADC 引脚的冲突。需要注意的是映射错了系统就完全不通排查通信问题时第一件事就是回头确认引脚映射配置和原理图是否一致。2.3 电压电流监测电路完整电源管理不能只负责“把电压变出来”还得知道当前电压是多少、电流在什么水平。电池电压直接关系到系统剩余电量低到阈值时需要做欠压保护避免锂电池过放。这里要用到电阻分压加 ADC 采样的经典结构。分压电阻的阻值选择有个矛盾阻值太小分压网络自己就一直在耗电阻值太大ADC 采样时由于采样电容的充电时间不够读数会偏低。我用了 1M 加 1M 的阻值组合等效内阻 500k配合单片机的 ADC 采样保持时间调整实测精度可以控制在 1% 以内。如果不需要连续监测还可以用 GPIO 控制分压网络的接地端只在测量时刻导通进一步省掉这路静态电流。电流监测方面最简单可靠的是低边检流电阻加运放放大。选检流电阻时先估算最大负载电流。我这个项目峰值 200mA用 50mΩ 电阻最大压降只有 10mV这个信号太小必须放大。PIC18LF46K42 内部自带运放增益配置成 50 倍输出就是 0V 到 0.5V落在 ADC 的输入范围内。这里要注意运放的失调电压本来 10mV 的满量程信号如果被 2mV 的失调吃掉 20%测量误差就太大了。实际调试时我先用万用表校准了一次分压和放大的总增益把误差校准到可以接受的范围。如果觉得内部运放调试麻烦也可以直接选带电流监测功能的 PMIC通过读取寄存器获得负载电流。我这次没有依赖这个功能主要是不确定它的精度和校准方式而且内部运放就在 MCU 里省零件也更灵活。3. 软件实现从初始化到动态调压、休眠唤醒3.1 I2C 底层配置顺序软件部分第一步是把 PIC18LF46K42 的 MSSP 外设配置成 I2C 主模式。K42 系列的 PPS 功能要先启用把 SCL 和 SDA 分别映射到对应引脚。接着设置波特率寄存器400kHz 快速模式下I2C 时钟来源于系统时钟需要按公式写入正确的分频值。主模式下的通信流程是发送 START发送设备地址加写位等待 ACK然后连续发送寄存器地址和数据最后 STOP。每一步都要检查中断标志位和 ACK 状态位不能只发不管结果。#define PCA9422_ADDR 0x60 // 实际地址由 ADDR 引脚电平决定以数据手册为准 void i2c_init(void) { // PPS 映射SCL - RB1, SDA - RB2 // 配置 MSSP 为主模式波特率 400kHz } uint8_t pmic_write_reg(uint8_t reg, uint8_t val) { i2c_start(); if (i2c_send_byte((PCA9422_ADDR 1) | 0) I2C_NACK) { return 0; } i2c_send_byte(reg); i2c_send_byte(val); i2c_stop(); return 1; }一个容易踩的坑是在 PMIC 完全上电之前不要去访问它。有些电源芯片在上电过程中数字部分还没复位I2C 接口对外的应答波形是乱的这时候总线上的通信会被拉死。稳妥做法是系统上电后先延时 10ms 以上确保 PMIC 内部稳定再发起第一次访问。另外如果 PMIC 支持读回寄存器初始化完之后一定要读一遍确认写进去的值防止通信过程中数据被干扰改写。3.2 PMIC 初始化序列初始化 PMIC 时我会按“电压配置、模式配置、输出使能、状态校验”的顺序走。先配置各通道输出电压再选择工作模式最后按计划的上电顺序逐个使能输出中间加必要的延时。电压配置的核心是理解 PMIC 的 VID 编程方式。很多低压 PMIC 的输出电压不是任意值而是按固定步进从基准电压向上累加。假设基准是 0.6V、步进 25mV那么要配 1.2V需要的配置码就是 (1.2 - 0.6) / 0.025 24转成二进制写入对应寄存器位。这个换算看起来简单但实际项目中是因为手册里的表格查起来容易眼花经常有人配错一个 bit 导致输出电压偏了 0.1V甚至高到把负载芯片烧掉。void pmic_init(void) { // 等待 PMIC 上电稳定 delay_ms(10); // 配置 Buck1 输出电压为 1.2V pmic_write_reg(REG_BUCK1_CFG, 0x18); // 配置 Buck2 输出电压为 3.3V pmic_write_reg(REG_BUCK2_CFG, 0x78); // 配置 LDO 输出电压为 1.8V pmic_write_reg(REG_LDO_CFG, 0x30); // 选择自动 PFM/PWM 模式 pmic_write_reg(REG_MODE_CFG, 0x01); // 上电时序先开 3.3V 主轨再开 1.2V 核心最后开 LDO pmic_write_reg(REG_EN_BUCK2, 0x01); delay_ms(1); pmic_write_reg(REG_EN_BUCK1, 0x01); delay_ms(1); pmic_write_reg(REG_EN_LDO, 0x01); }上电顺序这件事不同项目有不同偏好。我的习惯是先开外部传感器的 3.3V 主轨再开 MCU 核心的 1.2V 轨最后开模拟域的 1.8V LDO。原因是传感器上电瞬间可能有较大冲击电流趁 MCU 还没完全跑起来之前先把这阵冲击吸收掉避免核心逻辑在电源不稳时复位。具体顺序还是要看负载芯片的要求有的需要对处理器先上电、IO 后上电反过来会出问题。3.3 动态电压调节与休眠唤醒流程PCA9422 支持通过 I2C 实时调整输出电压这是这套方案比较有价值的地方。正常工作时核心电压 1.2V进入深度休眠前先把 Buck1 降到 0.9V关闭 Buck2 和 LDO只保留维持 MCU 唤醒逻辑所需的最小电源再执行休眠指令。整套流程对用户体现的就是“待机功耗进一步下降”对系统考验的是“唤醒之后能不能可靠恢复”。void enter_sleep(void) { // 降压核心电压从 1.2V 降到 0.9V pmic_write_reg(REG_BUCK1_CFG, 0x12); // 关闭不用的输出轨 pmic_write_reg(REG_EN_BUCK2, 0x00); pmic_write_reg(REG_EN_LDO, 0x00); // 配置 PIC 唤醒源定时器或外部中断 TMR1_Start(); SLEEP(); } void wakeup_process(void) { // 唤醒后先恢复电源再初始化外设 pmic_write_reg(REG_EN_BUCK2, 0x01); pmic_write_reg(REG_EN_LDO, 0x01); pmic_write_reg(REG_BUCK1_CFG, 0x18); delay_ms(2); // 外设初始化... }顺序不能搞反。如果先恢复外设电源、后恢复核心电压MCU 在电压不足的状态下访问外设可能导致总线状态异常甚至引起 GPIO 输出毛刺。恢复电压后再初始化外设等于给整个系统一个稳定的工作起点。另外要特别注意休眠流程里关闭输出轨之前先确认对应的负载设备已经进入了低功耗模式。如果无线模块还在发射状态下直接切断电源模块的状态寄存器会丢失下次上电要重新做一整轮初始化白白浪费唤醒时间而且瞬间断流还可能把模块的电源引脚打坏。3.4 监测与异常保护逻辑PIC18LF46K42 的 ADC2 有个很好的特性支持硬件过采样和自动平均。普通 ADC 需要 CPU 把每个采样结果读出来做软件平均而这个芯片可以配置成自动累加 32 次采样并求平均结果直接放到结果寄存器里CPU 整个过程中可以睡觉。这对电源监测这种需要“频繁但轻微关注”的任务太合适了既保证测量稳定又不占 CPU 时间。我的监测逻辑是每个主循环里读一次电池电压和核心电压滤波后判断是否越界。电池电压低于 3.3V 就进入低电量预警模式低于 3.0V 则直接关闭大功率负载只保留 MCU 和 RTC 供电保护锂电池不被过放。核心电压低于预期 5% 以上说明 PMIC 可能进入了限流状态或输出异常这时候系统会尝试重新初始化 PMIC从上电时序开始重新走一遍。还可以用 MCU 的硬件比较器做一个不依赖软件的紧急保护通道。把检流放大器的输出接到比较器正端负端接一个阈值电压比较器输出直接接到负载开关的使能端。负载电流一旦超过设定的阈值比较器输出翻转几百纳秒内切断负载不需要等 CPU 响应。这种保护对处理“MCU 卡死、软件看门狗来不及喂狗”的情况特别有效真正做到了硬件级别的安全兜底。4. 实测中踩过的坑与排查记录4.1 I2C 通信异常最初调试时遇到的最典型问题就是 PMIC 不响应表现为 MCU 发完地址后一直收不到 ACK。排查思路从硬件到软件一层层剥开。先用示波器看 SCL 和 SDA 波形确认有没有正确的 START 条件和地址帧再看信号幅值SDA 低电平和地之间是否超过了 0.4V如果没有说明上拉或灌电流有问题最后检查 PMIC 的供电电平和 I2C 地址引脚。这次的问题就出在地址引脚配置上我误把 ADDR 引脚悬空当成默认地址实际手册规定悬空电平对应了另外一个地址改过来就通了。现象可能原因解决办法无 ACKI2C 地址错误核对 ADDR 引脚电平与手册地址映射SCL/SDA 波形残缺上拉电阻过大减小到 2.2k 或按总线负载计算偶发通信错误电平域不匹配确认 PMIC I2C 引脚兼容 MCU 供电电平时序波形成锯齿总线电容过大缩短走线长度分组放置上拉4.2 输出电压偏低或偏高电压配置好之后实测输出 1.12V而配置目标是 1.2V。先排除配置码的问题读回寄存器确认写进去的值没错再测电感前端波形发现处于连续脉冲但占空比明显偏低。后来查到是工作模式的问题芯片在轻载时自动切到省电模式跳过部分开关周期输出电压会有一点纹波抬升或降低。把模式改为强制 PWM电压就稳了代价是轻载下静态电流会稍微增加。如果在电池供电场景对电压精度要求极高可以在这个模式下接受稍高的功耗或者通过软件每隔一段时间切换模式重新校准。还有一次输出电压偏高查下来是芯片手册里的 VID 表看串行了一个 bit 之差输出多了 100mV。这类问题很难通过波形发现最直接的方法是在原理图阶段就把需要配置的电压值列一个对照表软件填码时逐个核对而不是凭换算公式一把梭。4.3 休眠电流压不下去整机休眠电流要求 20 微安以内实测却有 180 微安。这是个非常经典的问题。我逐路断开排查最终定位到两处一是电池电压分压电阻 1M 加 1M 一直挂在电池两端典型情况下流过的电流就是 1.8 微安看着不大但如果还有多个分压网络叠加总量就上去了二是 I2C 上拉电阻接在了 3.3V 主轨上而 PMIC 的某个输出轨在休眠时被关断了上拉电阻通过 PMIC 内部电路倒灌电流。分压电阻的问题被我改成了 GPIO 控制的分压网络只在测量时接通。I2C 上拉改成接到常供电的 3.3V 轨而不是受控的输出轨。改完后整机休眠电流降到了 8 微安效果很明显。排查休眠电流不要靠猜用电流表串联电池逐个模块断电一次就能找到源头。4.4 ADC 采样读数不稳定电池电压读数在 4.10V 和 4.24V 之间跳幅度达到 0.14V这在做欠压保护时完全不能接受。先怀疑是参考电压问题MCU 的 ADC 参考用的是 VDD而 VDD 本身来自 Buck2负载变化会造成轻微跌落。于是分压点测量和基准值都叠加了电源噪声。后来把 ADC 参考改成内部固定参考电压同时对结果做 32 次硬件平均读数稳定到了 0.01V 以内。值得注意的是采样时机也有影响。无线模块在发射瞬间拉低 3.3V 轨此时采样电池电压会引入充电泵噪声尽量错开射频发射窗口读数更干净。ADC 测量这件事软件滤波只能救一部分问题根源还是硬件上的参考选择和采样时机设计。5. 个人经验与后续扩展思路5.1 PCB 布局上几个值得留意的细节电感是 PMIC 电路里最容易引发干扰的元件。摆放时尽量靠近 PMIC 的电感引脚走线要短而粗电感下方和周围不要铺铜避免涡流损耗影响效率。反馈走线要远离电感不然开关节点的磁场会耦合到反馈端导致输出电压纹波变大。模拟地信号通过一个单点连接到功率地既是噪声隔离也方便测试时用电流探头测量地环路。每个电压轨都预留一个测试点和跳线测试点在排障时直接接示波器探头看纹波跳线用来把某个负载和电源轨分开定位休眠电流来源。这些设计在原理图阶段多花十几分钟调试阶段能省半天到一天。5.2 这个方案的扩展方向用 PCA9422 和 PIC18LF46K42 的组合后续可以很自然地扩展出不少功能。比如把电池电压、负载电流、各路输出电压定时记录做一套简单的电量统计或者把 PMIC 的输出状态中断信号接到 MCU 的外部中断引脚一旦输出电压异常MCU 可以从休眠中被唤醒快速响应。如果产品需要支持太阳能充电可以在输入侧加入充电管理级PMIC 仍保持现有的多路输出架构不变。我的体会是电源管理方案在最开始就要把“测量、控制、保护、休眠”四条线同时考虑进去而不是先搭一个能跑的电源之后再慢慢打补丁。先把工作模式对应的功耗清单列清晰再选器件定配置后面改板的概率会小很多。
返回列表