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

PCA9422与MK60DN512手持终端低功耗电源设计

PCA9422与MK60DN512手持终端低功耗电源设计 ★ FEATURED ARTICLE
PCA9422 加 MK60DN512 这个组合我在一台手持数据采集终端上完整走过一遍从选型、画板、打样、飞线改板到最后把整机待机电流压进 30 µA 以内。这篇记录讲的是便携设备里那颗电源管理芯片 PCA9422 怎么和 MK60DN512 这颗 Cortex-M4 主控配合把电池、充电、多路电压、低功耗这几件事串成一套能跑起来、能量产的系统。它解决的核心问题是单节锂电供电的便携设备如何用一颗 PMIC 管住 2 路 BUCK、4 路 LDO 和一条充电回路同时让主控在 RUN、VLPR、LLS 之间干净地来回切。适合正在做低功耗手持设备、电池供电仪表、便携采集终端的硬件和固件工程师看也适合刚接手别人板子、面对一堆上电时序问题的人对照排查。文中所有参数、寄存器名都以我手上那版手册为准你复现时务必拿自己的数据手册核一遍尤其是寄存器地址和电压档位表厂家的修订版之间确实会有出入。1. 系统电源架构与选型为什么是这两颗芯片1.1 需求先摆上桌便携设备的五个硬指标做电源方案最怕上来就挑芯片正确的是先把需求量化。这台设备内部代号模拟项目 A的需求最后收敛成五条第一单节锂电 3.0–4.2 V 供电容量 800 mAh整机目标续航不低于 20 小时第二支持 5 V 输入充电充电电流要能设到 0.5 A 左右并且必须有过温降流因为设备会贴着人手用第三主控要 3.3 V传感器要 1.8 V模拟基准要一路干净的低噪声电源显示屏逻辑单独一路并且能关断第四关机状态整机漏电低于 50 µA否则放抽屉三个月电池就废了第五板子面积受限PCB 只有 40 mm × 60 mm电源部分不能超过 15 mm × 20 mm。把这五条翻译成器件语言其实就是需要一颗带充电器、带多路可配置输出、支持 I2C 动态调压、静态电流低的 PMIC加一颗能在低功耗模式下把外设全部关掉、自己只吃几微安的主控。PCA9422 恰好是这类需求的典型答案——它把线性充电、两路 BUCK、四路 LDO 和一套 I2C 寄存器映射塞进一个小封装里MK60DN512 则是那种该有的低功耗模式都有、外设足够多、生态成熟的 Cortex-M4VLPR 下内核降到很低频率跑LLS 下 RAM 保持、只留少数唤醒源。这里有个容易忽略的点需求里的续航 20 小时和漏电低于 50 µA其实是两个不同的设计目标前者由平均功耗决定后者由关断路径决定。很多项目死在第二条上——工作电流做得漂亮关机漏电却有 2 mA因为某一路 LDO 根本没关或者 MCU 的某个引脚在掉电时经由 IO 口倒灌。所以选 PMIC 的时候我一直把每一路能不能独立关断看得比效率高 2%更重。1.2 分立方案 vs PMIC 方案算一笔账在定 PCA9422 之前我确实认真算过分立方案的账。分立做法是一颗充电 IC 加两片 DC-DC 加三四片 LDOBOM 上大概多出 6 到 8 颗器件成本看着差不多但真正的代价不在钱上。第一是面积。两片同步降压每片要配电感、输入输出电容加起来至少吃掉 10 mm × 12 mm再塞四路 LDO 和充电 IC15 mm × 20 mm 的预算根本打不住。PMIC 把这些集成进去外部只需要电感和电容实际占位压到了 12 mm × 16 mm。第二是时序。分立方案里哪一路先起、哪一路后起、主控复位什么时候释放全靠自己搭 RC 或者写 GPIO 逻辑第一版调出来的时序经常在低温或者电池电压偏低时错乱。PMIC 的好处是这些顺序写在寄存器里出厂就是确定的不需要 MCU 参与MCU 还没上电的时候电源树已经按正确顺序起来了。第三是可测性。分离方案的每一路都要单独留测试点、单独验证PMIC 可以在固件里把每一路的输出电压读回来有些通道支持回读也可以在产线上通过 I2C 一键切换测试模式。这一点在量产阶段价值极高后面第 5 章会展开。代价当然也有PMIC 的寄存器配置一旦写错表现出来是整机不启动这种最恶心的现象而且你还不能用万用表立刻判断是硬件还是配置问题。所以用 PMIC 的项目我从第一版开始就要求所有电源相关配置必须做成表能一键导出、能对比 diff绝不能散落在代码各处。注意PMIC 的默认输出电压通常在出厂时已经由内部 OTP 或者 VSET 引脚分压决定了MCU 只需要改自己关心的那几路。如果你一上来就在初始化里把所有寄存器刷成自己的值很容易把充电参数或者保护阈值一起冲掉导致电池充不满或者充不进。我的做法是先读一遍全部寄存器存档再只改需要改的位。1.3 电压域划分与时序依赖最终的电压域划分是这样定的这张表后来被我贴在了调试台的墙上电源域来源输出电压供电对象是否可关断备注VDD_COREBUCK13.3 VMK60DN512 主电源、I2C 上拉、外设逻辑否主域常开VDD_SENSORBUCK21.8 V传感器、射频模块数字域是空闲时关断VDDA_REFLDO13.3 V主控模拟电源、ADC 参考否单独滤波远离 SW 节点VDD_LCDLDO22.8 V显示屏逻辑是息屏关断VDD_SDLDO33.3 V存储卡是拔卡检测后关断VDD_RTCLDO41.8 V保持域、RTC 备份否微安级负载VBAT_SENSE内部分压—电池电压采样—校准后使用BUCK1 是唯一不能关的一路因为主控靠它活着。BUCK2 和 LDO2、LDO3 都设计成用完就关这是待机功耗能压下来的关键——传感器和屏幕这两块如果常供电光静态电流就能吃掉 400 µA。时序上的依赖关系必须画清楚VBUS 或 VBAT 接入后PMIC 内部先建立基准然后 BUCK1 起振3.3 V 稳定后主控的 POR 电路释放复位MCU 开始跑启动代码MCU 起来之后才通过 I2C 去打开 BUCK2 和其他 LDO因为传感器和屏幕都不允许在 3.3 V 建立之前就上电否则会出现 IO 倒灌。这条规则反过来也成立关机时先关外设域等 100 ms 再让 MCU 进入深度睡眠或者干脆切断自己。我第一次画板的时候把 LDO2 的输出接到了一个常开的电平转换器上结果关机漏电直接飙到 1.8 mA找了半天才发现是电平转换器的电源脚没断。这个坑后面还会提到。2. 硬件落地原理图与 PCB 上真正决定成败的细节2.1 输入、电池与充电回路的器件取值充电回路的输入是 5 V走 USB 接口进来串一颗理想二极管或者直接用 PMIC 内部的路径管理。PCA9422 这类芯片一般支持输入和电池之间的自动切换外部只需要在 VBUS 上放一颗合适的输入电容典型 4.7 µF 到 10 µF 的 X5R 陶瓷电容耐压至少 10 V。这里我踩过一次坑第一版用了 6.3 V 耐压的 0603 电容USB 插拔瞬间的浪涌加上直流偏压效应实际容值掉到标称的一半都不到导致插入瞬间 VBUS 掉到 4.2 V 以下芯片反复进出欠压保护。换成 10 V 耐压、0805 封装之后问题消失。电池接口这边除了正常的 VBAT 走线我坚持加了三样东西一颗 TVS 管在电池座和 PMIC 之间做浪涌钳位一颗 NTC 热敏电阻贴在电芯上接到 PMIC 的温度检测脚以及一个 0.01 Ω 的采样电阻如果用的型号支持库仑计。NTC 这一条特别重要因为它直接决定了 JEITA 温度补偿能不能生效。便携设备在夏天车内或者冬天户外使用时如果没有温度保护轻则充不满重则电芯鼓包。提示NTC 的 B 值和 25 ℃ 阻值必须和 PMIC 内部预设的曲线匹配否则温度读数会整体偏移。我见过有人随手拿了颗 10 kΩ B3950 的结果手册要求的是 10 kΩ B3435高温段判断晚了十度。选型时对着手册的 NTC 推荐表抄别自己发挥。充电电流的设定有计算公式通常是 I_CHG V_ISET / R_ISET × 某个系数或者直接写寄存器。0.5 A 对 800 mAh 电芯来说是 0.625C属于偏激进的档位所以我实际设的是 400 mA0.5C并且在固件里做了一件事检测到 USB 枚举为低电流端口比如只识别成 100 mA 设备时把充电电流降到 100 mA避免把主机口拉挂。2.2 BUCK 电感电容的选型计算BUCK 的参数不能拍脑袋。以 BUCK1 为例输入取电池的典型值 3.7 V输出 3.3 V开关频率手册标称 2 MHz最大负载按 400 mA 算主控 100 MHz 满载加上外设。电感量的选择要让纹波电流落在额定输出电流的 20% 到 40% 之间。公式是ΔI_L (V_IN − V_OUT) × V_OUT / (L × V_IN × f_SW)代入 ΔI_L 目标 100 mAL (3.7 − 3.3) × 3.3 / (0.1 × 3.7 × 2×10⁶) ≈ 1.32 / 740000 ≈ 1.78 µH取标称值 2.2 µH反算纹波电流约 81 mA占 400 mA 的 20%很合适。电感的饱和电流要留足余量我选的是 1.5 A 饱和、直流电阻 60 mΩ 以内的屏蔽电感尺寸 2520。别贪便宜用非屏蔽的绕线电感2 MHz 下辐射能把旁边那颗高阻输入的 ADC 通道干扰到没法看。输出电容按纹波要求算。忽略 ESR 的理想情况下ΔV_OUT ≈ ΔI_L / (8 × f_SW × C_OUT)想让纹波控制在 5 mV 以内C_OUT ≥ 0.081 / (8 × 2×10⁶ × 0.005) ≈ 1.0 µF。但实际工程里没人会只放 1 µF因为还要考虑负载瞬态和直流偏压衰减。我的实际配置是 22 µF0805X5R6.3 V 100 nF实际示波器测下来峰峰值 8 mV 左右其中大部分是开关尖峰而不是三角波。如果对纹波敏感可以在反馈点附近再加一颗 10 pF 的前馈电容改善相位裕度。输入电容同样关键。BUCK 的输入电流是脉冲的必须在芯片的 PVIN 脚旁边放 10 µF 100 nF并且 100 nF 要尽可能贴近引脚距离超过 3 mm 就基本失去意义了。2.3 布局布线与地平面的处理电源板的成败八成在布局。我总结了几条死规矩每一条都是被现实教育过的SW 节点电感输入端的铜皮面积越小越好够过电流就行多出来的每一平方毫米都是天线。同时这一层下面必须有完整的地平面做屏蔽。反馈走线必须从输出电容的正极取走内层或者贴着地走绝对不允许从电感下方穿过也不允许和 SW 节点平行走超过 2 mm。输入电容的地和芯片的 PGND 要直接连用最短路径不要绕。电池负极和系统地之间单点连接位置放在 PMIC 的 PGND 附近这样充电大电流不会流过 MCU 下方的地平面。模拟电源LDO1 输出单独铺一小块铜用磁珠或者 0 Ω 电阻从主 3.3 V 上取电滤波电容靠近 MCU 的 VDDA 引脚。还有一个容易被忽略的点MK60DN512 的复位脚和 PMIC 的复位输出之间的连接。如果 PMIC 有独立的 nRESET 输出接过来的时候要配电平匹配和 RC 滤波因为复位线上很容易串入 BUCK 的开关噪声导致 MCU 随机复位。我第一版就遇到过这个问题整机偶尔跑几小时就死一次最后在复位脚上加了一颗 100 nF 到地问题彻底消失。注意地平面千万不要模拟地数字地各自完整、中间用一根线连这种教科书式分法。在 2 MHz 开关频率加 100 MHz 主控的组合下这么做只会制造更大的环路。正确做法是整块完整地平面靠布局把大电流路径和敏感信号物理隔开而不是靠割地。3. 软件侧I2C 驱动与电源状态机3.1 MK60DN512 的 I2C 底层封装MK60DN512 的 I2C 是经典的外设模块寄存器包括地址寄存器 A1、分频寄存器 F、控制寄存器 C1、状态寄存器 S 和数据寄存器 D。我把它封装成两层底层是最小可用的读写事务上层是按寄存器名操作 PMIC 的封装。/* PMIC 的 7 位地址按手册确认后再改这里 */ #define PMIC_I2C_ADDR 0x4B #define PMIC_REG_MAX 0x40 static int i2c_wait_flag(uint8_t flag) { uint32_t timeout 100000; while (!(I2C0_S flag)) { if (--timeout 0) return -1; /* 超时保护必须有 */ } return 0; } /* 写一个字节START - 地址W - 寄存器 - 数据 - STOP */ int pmic_reg_write(uint8_t reg, uint8_t val) { I2C0_C1 I2C_C1_IICEN_MASK | I2C_C1_TX_MASK; I2C0_C1 | I2C_C1_MST_MASK; /* 产生 START */ I2C0_D (PMIC_I2C_ADDR 1) | 0; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; /* 写 1 清标志 */ if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } I2C0_D reg; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } I2C0_D val; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } i2c_stop(); return 0; }读事务要复杂一点因为需要重复起始条件加切换方向/* 读一个字节START - 地址W - 寄存器 - 重复START - 地址R - 读 - NACK - STOP */ int pmic_reg_read(uint8_t reg, uint8_t *out) { I2C0_C1 I2C_C1_IICEN_MASK | I2C_C1_TX_MASK; I2C0_C1 | I2C_C1_MST_MASK; I2C0_D (PMIC_I2C_ADDR 1) | 0; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } I2C0_D reg; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } I2C0_C1 | I2C_C1_RSTA_MASK; /* 重复起始 */ I2C0_D (PMIC_I2C_ADDR 1) | 1; if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; if (I2C0_S I2C_S_RXAK_MASK) { i2c_stop(); return -2; } I2C0_C1 ~I2C_C1_TX_MASK; /* 切到接收 */ I2C0_C1 | I2C_C1_TXAK_MASK; /* 读完发 NACK */ (void)I2C0_D; /* 假读启动接收 */ if (i2c_wait_flag(I2C_S_IICIF_MASK)) return -1; I2C0_S I2C_S_IICIF_MASK; i2c_stop(); *out I2C0_D; return 0; }这两个函数后来被证明是整个项目里最值钱的东西因为所有电源问题的排查都是从能不能读到正确的寄存器值开始的。我建议你在第一版固件里就加一个pmic_dump_all()开机时把 0x00 到 0x3F 全部读出来打个 log后面 diff 配置的时候会救命。3.2 上电初始化序列与寄存器配置初始化绝对不能一口气写完。PCA9422 有些寄存器配置后需要等稳定的时间有些是写后立即生效顺序错了会出现输出电压抖动或者反复软启动。我的实际顺序如下延时确认 3.3 V 域已经稳定读一下内部状态寄存器的电源好标志或者干脆用软件延时 10 ms稳但慢。读一遍全部寄存器做备份存到backup[]数组里。配置 BUCK1 的输出电压档位如果和默认值一致就跳过——避免无谓的重新软启动。配置充电参数恒流值、终止电压、JEITA 使能、终止电流阈值。配置 LDO 各路输出先配置后使能。打开看门狗和欠压保护阈值。再次全部读回和预期值逐位对比不一致就记录错误码。这里有一个非常关键的细节电压档位的写入不是简单的线性映射。手册里给的是离散档位表每个寄存器值对应一个具体电压中间还有保留值。我一开始按线性公式算写了一个3.3 V 对应 0x1A结果读回来是对的但实际输出是 3.1 V。后来对着表查才发现 0x1A 在该芯片的映射里是另一个档位真正对应 3.3 V 的是 0x1C。从那以后我的配置表全部写成宏名 → 档位值的形式代码里不出现任何裸数字#define PMIC_VOUT_3V3 0x1C /* 按手册 Output Voltage 表核对 */ #define PMIC_VOUT_1V8 0x0E #define PMIC_VOUT_2V8 0x16 static const struct { uint8_t reg; uint8_t val; uint16_t delay_ms; } pmic_init_seq[] { { REG_BUCK1_CFG, PMIC_VOUT_3V3, 5 }, { REG_BUCK2_CFG, PMIC_VOUT_1V8, 5 }, { REG_LDO1_CFG, PMIC_VOUT_3V3, 2 }, { REG_LDO2_CFG, PMIC_VOUT_2V8, 2 }, { REG_CHG_CFG0, CHG_400MA, 0 }, { REG_CHG_CFG1, CHG_4V2_TERM, 0 }, };表格驱动的另一个好处是可测试。产线自检的时候我只需要把这张表和实际读回值比对就能在 2 秒内判断出这颗 PMIC 有没有写进去不用整机跑功能测试。提示不要在 MCU 启动的最早期就去操作 I2C。我踩过的坑是在SystemInit之后立刻配置 PMIC此时 3.3 V 刚建立电源还在爬升I2C 上拉电阻的电压不够出现间歇性 NAK。后来加了 20 ms 延时并加了三次重试问题彻底消失。重试策略是失败后先发 9 个时钟脉冲解锁总线再重新发起始条件。3.3 低功耗模式切换与唤醒路径设备的实际工作节奏是每 10 分钟采集一次采集耗时约 200 ms其余时间全部睡眠。所以功耗优化的核心是让睡眠态尽量深。我把状态分成四级状态主控模式电流实测唤醒源唤醒时间RUN100 MHz 全速38 mA——WAIT降频 24 MHz11 mA任意中断微秒级VLPR内核 4 MHz2.1 mA低频外设中断约 20 µsLLS停内核、RAM 保持18 µA引脚中断、RTC约 1.2 ms关机电源域关断6 µA按键从上电算起从 RUN 到 LLS 的路径要按固定顺序走中间任何一步漏掉都会让电流停在 2 mA 下不去第一步关外设电源。通过 I2C 把 BUCK2、LDO2、LDO3 全部关断等待 5 ms 让输出电容放电。 第二步把 MCU 的所有 GPIO 设成确定状态。输出脚保持输出低输入脚如果外部有上拉就配成下拉绝不允许悬空——悬空的输入脚在低功耗模式下会因输入级来回翻转吃掉几十微安。 第三步关掉不需要的模块时钟包括 ADC、SPI、UART只留 RTC 和唤醒引脚所在端口的时钟。 第四步配置唤醒源清所有挂起标志进 LLS。唤醒之后要做逆操作顺序反过来。这里有个经典陷阱唤醒后如果不重新初始化 I2C某些情况下总线会因为进入低功耗前正好处于事务中间而卡死。我的做法是唤醒后先发 9 个时钟的恢复序列再重新初始化 I2C 外设。还有一处必须处理进入 LLS 前要把 PMIC 的看门狗喂饱或者关掉。如果 PMIC 的看门狗在睡眠期间超时它会直接把主控复位表现出来就是设备每隔几分钟自己重启一次而且很难查——因为日志还没来得及写就被复位了。3.4 充电状态机与电量上报充电这一块PMIC 内部基本把恒流恒压的活干完了MCU 要做的是状态机管理和电量估算。状态机很简单五个状态未接充电器、预充、恒流、恒压、充满。状态通过 I2C 读 PMIC 的状态寄存器获得同时结合电池电压判断。这里有个细节不能只看状态寄存器因为它有滞后我加了双重判断状态寄存器说充电中并且电池电压在 30 秒内确实在上升才认为状态有效否则视为异常触发告警。电量估算我没有用库仑计直接积分的笨办法而是做了分段拟合。开路电压法在锂电池上误差很大尤其是 3.7 V 附近几乎是一条平线所以我的做法是在充电和放电过程中用库仑计累积电荷量同时用电压做末端校正——充到 4.2 V 转恒压且电流降到终止阈值时把电量强制校准到 100%放到 3.4 V 时校准到 5%。中间段完全靠积分。这套逻辑实测下来日常使用误差控制在 3% 以内。电压采样要注意分压电阻的选取。电池电压 4.2 V 经过分压进 MCU 的 ADC分压比选 1/2 的话4.2 V 对应 2.1 V在 3.3 V 参考下分辨率够用。但分压电阻不能太小否则常态漏电。我用的是 1 MΩ 1 MΩ静态漏电 2.1 µA可以接受同时并联 100 nF 做 RC 滤波时间常数 50 ms配合软件做 16 次平均读数很稳。注意分压电阻这条路径在关机状态下依然存在漏电如果你的关机漏电指标卡得很死比如 20 µA就必须在分压电阻下端串一个 MOS 管只在采样的时候打开。我第二版就是这么改的直接省下 2 µA。4. 调试实录从首板不亮到稳定运行4.1 首板上电的检查顺序第一版板子回来的时候我的习惯是先不焊 MCU只焊电源部分用可调电源从电池脚灌 3.7 V限流设 100 mA。这么做的好处是万一电源部分有短路限流能保住芯片。检查顺序是固定的先用万用表量各路的对地阻抗正常情况下 3.3 V 对地应该在几十 kΩ 以上如果是几欧姆说明有短路先别上电。然后上电量 VBAT 脚电压再看 BUCK1 输出有没有 3.3 V。如果没有第一件事是量使能脚和 VSET 脚的电压很多输出不来的问题其实是使能条件没满足。我这次的实际情况是BUCK1 输出只有 1.2 V 左右而且抖。第一反应是反馈分压焊错了检查发现是反馈电阻的一颗焊盘虚焊——回流焊的时候那颗 0402 的电阻一侧立了起来。补焊之后 3.3 V 正常。这也是为什么我后来在打样板的时候电源部分全部用 0603虽然占面积大一点但立碑的概率低得多。电源正常之后才焊 MCU再上电看电流。第一次上电电流应该是几毫安到十几毫安如果直接冲到 100 mA 限流值说明有地方短路或者 IO 打架。4.2 故障排查速查表下面这张表是我在这个项目里实际遇到的按出现频率排序现象最可能原因排查手法最终处理I2C 访问 PMIC 一直 NAK地址错、上拉缺失、PMIC 未上电示波器抓 SDA/SCL看第 9 个时钟是否有 ACK地址从 0x48 改为 0x4B重新确认手册输出电压比设定值低 0.2 V档位值写错落在相邻档逐档扫描并测量实际输出建立档位对照表代码里只用宏插 USB 时反复重启VBUS 输入电容耐压不足欠压保护抖动示波器抓 VBUS 波形看跌落深度换成 10 V 耐压 0805容值加大睡眠电流 2 mA 下不去GPIO 悬空或某路 LDO 未关逐个断开外设电源域测电流加上拉/下拉配置关断 LDO2/LDO3充电充到 90% 就停终止电流阈值设太高或 NTC 触发降流读充电状态寄存器和温度寄存器调整终止阈值校准 NTC 曲线运行几小时后随机复位复位线串入开关噪声示波器抓复位脚看有无毛刺复位脚加 100 nF 到地低温下不充电JEITA 保护生效读温度寄存器确认属正常保护需在 UI 上提示用户电量显示跳变电压法采样受负载影响对比库仑计积分值改为积分 端点校正这张表里最值得说的是第一条。I2C 不通这种问题新手最容易陷进代码是不是写错了的死循环实际上 90% 是硬件问题上拉电阻没焊、地址搞错、或者 PMIC 根本没上电。正确的排查顺序永远是先硬件后软件用示波器看波形比看代码快十倍。4.3 示波器上的三个关键波形第一个是 BUCK 输出的纹波。测量方法很讲究绝对不能用示波器探头的地线夹那个夹子形成的环路会把开关噪声全部引进来测出来几百毫伏的纹波其实全是测量误差。正确做法是用地弹簧探头自带的短地针直接顶在输出电容的地端带宽限制开 20 MHz。这么测下来3.3 V 输出的峰峰值是 8 mV可以接受。第二个是上电时序。双通道探头一路抓 VBAT一路抓 3.3 V 输出触发设在 VBAT 上升沿。理想波形是 VBAT 到位后 2 到 3 ms 内 3.3 V 开始爬升爬升时间 200 µs 左右单调上升无回勾。如果看到回勾说明软启动或者负载有问题多半是输出电容太大或者负载电流超了。第三个是复位释放时刻。三通道同时抓 3.3 V、复位脚、I2C 的 SCL。正常应该是复位在 3.3 V 达到 90% 之后至少 1 ms 才释放MCU 起来后第一批 I2C 事务要在 3.3 V 完全稳定之后。我第一次测的时候发现复位释放得太早MCU 在 3.0 V 就开始跑了虽然大部分时候能起来但低温下就会挂。后来调整了 RC 时间常数才解决。4.4 功耗实测与续航核算功耗是用高精度电流表加分段统计做的不是靠估算。实测数据如下工作阶段持续时间电流单次电荷量唤醒 初始化30 ms15 mA0.45 mC采集 处理200 ms38 mA7.6 mC数据存储100 ms22 mA2.2 mC睡眠599.67 s18 µA10.8 mC单周期合计600 s—约 21 mC单周期平均电流 21 mC / 600 s 35 µA。用 800 mAh 电池考虑放电深度只取 80%640 mAh 可用理论续航约 640 / 0.035 ≈ 18 天。这个数字远超需求里的 20 小时说明设计余量充足后面即使加上无线上报也能撑住。但这里有个陷阱上面的睡眠电流是在 25 ℃、电池满电的条件下测的。实际使用中如果设备放在低温环境电池内阻上升同样的负载下电池端电压会掉得更快可用容量可能只剩 60%。所以做续航核算时我一般会乘一个 0.7 的系数报出去的数字才靠谱。另外休眠电流的测量本身很容易出错。用普通万用表串在电池回路里表的内阻会让电路根本进不去深度睡眠正确做法是用专门的微安级电流表或者用高边采样电阻配合差分放大。我一开始用万用表测出来 400 µA折腾了半天换表之后发现真实值是 18 µA。5. 迭代与量产前的复核清单5.1 我在第二版改掉的五个地方第一版能跑但从工程角度有很多将就。第二版我改的第一件事是把所有电源测试点引出来每个电压域留一个 1 mm 的测试焊盘调试时探针一戳就行不用再到处找电容。这个改动几乎零成本但调试效率提升巨大。第二件是把电池分压采样加上了 MOS 开关前面提过直接省了 2 µA 漏电。第三件是把 PMIC 的 NTC 走线改成了差分屏蔽走线从充电回路旁边挪开之前温度读数会跟着充电电流跳。第四件是把复位线的 RC 从 10 kΩ 10 nF 改成 100 kΩ 100 nF时间常数接近但驱动能力要求的电流小了抗干扰反而更好。第五件也是最值的一件我把所有电源配置做成了一个独立的配置块编译时可以切换调试模式和量产模式。调试模式打开所有保护、输出详细日志量产模式关掉日志、缩短延时、提高启动速度。这个改动让同一份代码既好调又好产。5.2 出厂自检脚本的思路产线自检最怕的就是测了等于没测。我的自检脚本做了四件事每件都能给出明确的 pass/fail第一读回 PMIC 的全部关键寄存器和预期值逐位对比。这一项能抓住焊接不良、I2C 虚焊、PMIC 装反这些问题。第二依次打开每一路输出测量电压是否在 ±5% 窗口内然后关掉。这一项能抓住电感虚焊、输出电容缺失。第三模拟充电器接入用外部电源从 VBUS 灌 5 V检查充电状态寄存器是否切换充电电流是否在设定值附近。第四整机进入睡眠用治具上的电流表测 30 秒平均电流超过阈值直接判失败。这四项跑下来大约 8 秒能覆盖 95% 的产线不良。其中第四项最容易被忽略但它恰恰是最容易出问题的一项——因为睡眠电流依赖软件的 GPIO 配置任何一个引脚的配置改动都可能让电流翻十倍。最后一个心得也是我在这个项目里体会最深的一点电源系统的调试七成的时间花在确认问题到底在哪一层。是硬件虚焊、是寄存器配置、还是软件时序我的做法是在第一版就把 PMIC 的寄存器读写和电压测量做成命令行的调试命令通过串口就能触发不用重新烧固件。这套东西花了大概两天写但后面每一次排查都省下了重新编译、烧写、复位的十分钟。当你在深夜里第 20 次怀疑自己是不是把某个寄存器写到保留位上的时候能在两秒内把所有寄存器的当前值打出来那种感觉是值得的。
阅读完成 · 觉得有帮助?
咨询建站