锂电池储能和备用电源里,最容易被低估的就是串联电池组的均衡问题。很多人觉得只有 4 串、8 串以上才需要认真做均衡,实际上哪怕只是 2 串电池,在备用电源这种长期浮充、间歇放电的场景下,也照样会因为一致性漂移而提前退役。最近我完成了一套 2 串磷酸铁锂备用电源样机,核心方案是 MP2642GR-Z 负责电池间的电荷搬移,PIC18LF45K50 做主控,做电压采集、均衡算法和通信管理。这篇文章把选型逻辑、硬件细节、固件状态机以及整机调试中踩过的坑完整梳理一遍,给同样在折腾小型 BMS 的人一个可以直接参考的样本。
1. 为什么两节串联电池也需要认真做均衡
1.1 两节电池的一致性不是出厂定死的
先说个很多人理解偏差的地方:电池组出厂做过配组,不代表后续一直保持一致。所谓“一致性”,是一个随时间衰减的变量。两节电池串联,流过它们的电流完全相同,但每节电池的内部状态却可以越走越偏。
主要来源有三类。第一是制造公差,即便同一批次,极片厚度、电解液浸润程度、隔膜透气性都会有微小差异,表现出来的就是容量、内阻、自放电率不完全一样。第二是温度分布,备用电源机箱内部不是等温场,两节电池如果有一节靠近功率器件或者散热孔,温度差上几摄氏度非常正常,而温度直接影响自放电速度和内阻,时间一长就把初始差异放大了。第三是同一个电池组内部的 SOC 校准问题,充电曲线和放电曲线都不是完全可逆的,反复充放电后两节电池的可用容量会发生错位。
在 2 串拓扑里,因为两节电池没有并联关系,容量小或者自放电快的那一节会先被充满、先被放空。如果系统没有均衡机制,每次充电都会让高压那节更容易出现过压保护,低压那节永远充不满;每次放电则反过来,低压那节先触发欠压保护,高压那节还有电但已经无法输出。日积月累,短板越来越短。
1.2 被动均衡为什么在备用电源里不够用
低成本 BMS 上最常见的均衡方式是电阻耗散式被动均衡。基本原理是检测到某节电池电压偏高时,把并联在该电池两端的 MOS 管打开,让多余的能量通过大功率电阻放掉,直到电压和其他电池接近。
这个方案的优势很直接:电路简单、器件便宜、控制逻辑不复杂,一颗普通 IO 加两颗 MOS 和两颗电阻就能实现。但它的短板也恰好卡在备用电源最在意的几个点上。
首先是热问题。被动均衡的均衡电流一般只有 50~200mA,高于这个范围就会在电阻和 MOS 上产生非常可观的功耗。100mA、两只电池压差 50mV 时看似功率不大,可均衡通常不是几分钟,而是要持续几十分钟甚至几小时。密闭机箱里,发热会导致电池温度升高,温度又拉大自放电差异,得不偿失。
其次是效率问题。被动均衡本质是“把多余能量变成热量扔掉”,不是“把能量从高的一节搬到低的一节”。在储能和备用电源系统里,能效是硬指标,尤其当系统长期待机、只有少量浮充电流时,拿电阻把几瓦能量烧掉,逻辑上就很亏。
所以我的结论是:被动均衡只能作为低成本的底线方案,用在无明显热约束、对寿命要求不高的产品里。一旦把“长期浮充、温度有限、寿命三年以上”作为设计目标,主动均衡才是正路。
1.3 方案选型:为什么用均衡 IC 加 MCU 而不是专用 BMS AFE
做 2 串电池管理,市面上有很多集成的 BMS 模拟前端芯片,采样通道、保护逻辑、均衡驱动基本都做好了,理论上最省事。但实际评估后我放弃了这条路,原因有三个。
一个是通道浪费。大部分模拟前端最少支持 3~4 节电池,为 2 节电池买单显然不划算,而且芯片体积、引脚数、外围电路对小系统来说都偏重。另一个是均衡能力。多数 AFE 自带的均衡是“以被动方式为主”,少数支持主动均衡的则需要外挂电感、变压器和独立的控制时序,芯片本身并不直接解决功率级问题。换句话说,选 AFE 省的是采样和保护,均衡功率还得另外设计。
第三个原因是场景定制不够灵活。备用电源、家用储能柜、小型 UPS 这类系统,均衡策略跟充电策略、负载调度、通信协议强相关。比如备用电源长期浮充时,可能希望每天只在固定时间段做一次小电流均衡,其余时间主控休眠;也希望能通过通信接口看到两节电池的压差变化趋势。专用 AFE 虽然也可以调参数,但绕弯路的次数比直接写 MCU 逻辑多得多。
所以最终定了两层架构:MP2642GR-Z 承担功率级均衡的开关、电流控制和保护,PIC18LF45K50 负责采样、算法、状态机、通信和低功耗调度。均衡能力由专用芯片保证,策略灵活性由 MCU 保证。这相当于把“硬件上的搬移”和“软件上的决策”解耦开,后面调试时优势非常明显。
2. 硬件搭法:从电池到 MCU 的完整通路
2.1 功率级外围:少踩电感布局的坑
MP2642GR-Z 这类的均衡控制芯片,内部实际上把驱动、逻辑控制、电流检测和功率开关集成得比较完整,外部真正需要搭的只是储能电感、输入输出电容和采样电阻。这也是我选它的重要原因,功率部分不用自己画半桥驱动、不需要自举电容,外围清爽很多。
拓扑上,两节串联电池之间的主动均衡常用“电感储能 + 交替搬运”的方式。简单说就是:当第一节电压高于第二节,芯片把第一节的能量先灌入电感,然后再让电感对第二节放电;反过来也一样。整个过程中电能不是被消耗掉,而是从一节电池搬到了另一节,所以效率和均衡能力都优于电阻方案。
具体器件选择上,电感我建议按最大均衡电流去选,不要只按平均电流。比如目标均衡电流 0.8A,峰值可能达到 1.2A 甚至更高,电感额定饱和电流至少要达到峰值的 1.5 倍以上,否则电流纹波一大,电感叫声和发热会非常明显。感值方面,我们最终用了 22μH。感值越大,开关纹波越小,但动态响应和效率会受影响;感值太小,峰值电流容易超过限流点。最终还是以芯片数据手册里的推荐区间为主,再根据实际温升微调。
容量上,每个电池单元旁边要放低 ESR 的陶瓷电容,我习惯是 10μF 配 0.1μF,而且尽量靠近芯片的功率引脚。很多人在布局时图方便,把滤波电容放到背面很远的地方,结果开关噪声一大片,ADC 采样全被污染。主动均衡的开关频率一般都在几百 kHz 量级,功率回路的几何面积直接决定环路电感,环路电感越大,电压尖峰越难看。
还有一点,电感的摆放方向最好不要靠近采样电阻,否则磁场会在采样回路上感应出噪声,直接影响均衡电流的稳定性。实测中,把电感旋转 90 度后,示波器上看到的采样电阻纹波幅度能下降一半以上,这个细节很值得注意。
2.2 电压采样链路:精度靠校准,抗扰靠滤波
主动均衡的效果好不好,根本上取决于主控能不能准确判断“哪一节电压高、高了多少”。PIC18LF45K50 内部有 ADC,但电池电压不能直接接进去,需要经过电阻分压。
这里有个容易犯的错误:为了降低静态功耗,有些人喜欢用兆欧级的大电阻分压,结果 ADC 采样时因为输入阻抗不够,采样值明显偏低。解决办法是在 ADC 引脚前加一个小阻值的 RC 滤波,以及把 ADC 采样时间设置得足够长。我们实际用的分压电阻总值在 200kΩ 左右,ADC 前加 1kΩ 串阻和 0.1μF 电容,效果比较均衡,既不会明显增加电池静态功耗,也不会拉低采样精度。
但分压电阻本身有精度问题。常用 1% 电阻会带来约百分之几的原始误差,放在 3.6V 量程上看就是几十毫伏的偏差,这远远大于均衡需要的精度。所以不能只靠硬件精度,必须做软件校准。我的做法是:样机贴片前先用高精度数字万用表标定每一组分压电阻的实际比例,再把校准系数写进设备配置区,之后每次上电采样都按比例修正。这样实测电压误差可以压到 5mV 左右,对 20mV 级的均衡阈值来说已经够用。
采样滤波也不能敷衍。均衡芯片工作时会在电池端产生周期性的电流变化,电压有纹波是正常的。如果直接拿原始 ADC 值比较,算法会不停抖动,均衡开关频繁切换。我在固件里用了“去掉最大最小值的移动平均”,每次采集 10 个点,去掉一个最大值和一个最小值,剩下的 8 个取平均。这样既不丢失真实电压变化,也能滤掉开关毛刺。
2.3 电源、使能与保护:不让主控比电池先倒下
PIC18LF45K50 是低压 MCU,而电池组电压在 5V 到 8.4V 之间,需要 LDO 降压供电。这里有个很实际的问题:均衡器工作时,电池电压会因为负载而出现快速波动,如果 LDO 前端走线太长,MCU 可能在均衡启动瞬间复位。
我的建议是:LDO 输入电容要足够大,至少 22μF,并且放在电池端子和 LDO 之间,而不是放在主控板远端。如果系统里还有其他负载,最好让主控供电单独走一条线,从电池端子处直接拉,避免经过功率输出的大电流路径。
均衡使能信号必须由 MCU 控制,但不能只靠软件慢悠悠地关断。板上要有一个 RC 延时电路配合硬件逻辑,让 MCU 一旦检测到异常,可以立即把使能脚拉低,同时硬件路径上不允许在没有 MCU 控制的情况下自动恢复。备用电源系统最忌讳的是故障后悄悄恢复,然后再次故障,所以故障锁定是必须的。
保护方面,除了保险丝和反接保护,一定要加电池温度采样。MP2642GR-Z 这类芯片能处理电气故障,但热故障是它控制不了的,NTC 热敏电阻放在两节电池之间,通过分压直接接 MCU 的 ADC,固件里做一二级温度保护:超过 45℃ 把均衡电流降一半,超过 60℃ 直接禁止均衡。
3. 均衡控制逻辑与 PIC18LF45K50 固件实现
3.1 先搞清楚均衡电流和电压测量之间的矛盾
这可能是整个项目里最容易想歪的地方。均衡本身就是一种对电池的扰动:主动均衡在工作时,会有数百毫安电流流进或流出某一节电池,电池内阻会因此产生电压降。也就是说,均衡开启的瞬间,采样到的电压并不是真实的开路电压,而是带负载后的端电压。
如果固件不做处理,就会出现一个很滑稽的现象:第一节电压高,开始向第二节搬电,结果第一节电压因为负载而跌下来了,第二节电压因为被充电而涨上去了,算法以为方向反了,于是又往反向搬。来回切换,电池没均衡好,空耗能量,还可能引起振荡。
解决思路有两个层次。第一层是在均衡停止的间隙采样。比如每秒钟关断均衡 10ms,等电池端电压稳定后再采一组值,用这个值去判断是否继续均衡。第二层是根据电流方向做端电压补偿,需要知道电池内阻和当前均衡电流,公式是 V_ocv = V_terminal - I_discharge × R_internal,但这个对参数准确性要求高,一般用在更复杂的 BMS 上。对 2 串系统来说,我最终采用的是“停均衡再采样”策略,简单可靠,代价是均衡占空比会低一点,实际测试下来整体效率依然可以接受。
3.2 三段式状态机比 PID 更好用
之前有个项目里我试过用 PID 去连续调节均衡电流,想要让压差平滑收敛到零。想法很理想,实践很痛苦:PID 参数对电池内阻、SOC、温度都太敏感了,同一个系统在冷机与热机状态下性能差很多,很难调出一个稳定参数。
后来把策略改成三段式状态机,简单粗暴但非常稳。第一段是“判断待命”,主控周期性采集两节电池电压,计算压差。只有压差超过 20mV 时才进入均衡,低于 10mV 且持续 10 秒以上才退出,中间的区间全是滞回区,防止频繁切换。
第二段是“方向执行”,根据压差方向确定搬移方向:第一节高就往二节搬,第二节高就往一节搬。这个方向要保持足够长的时间,至少几十秒,不允许像 PID 那样连续反转。电池均衡本来就是个缓慢过程,刚从充满电的电池往亏电电池搬了几秒,不可能立刻见效,方向频繁变化是浪费。
第三段是“停止检查”。均衡不是一直开到底的,要周期性停止,重新测量真实压差。如果还没到目标就继续,如果到了就直接关闭。整套逻辑用状态机写很清晰,也方便把故障状态插进去。
伪代码大致是这样:
typedef enum { IDLE, BALANCE_A_TO_B, BALANCE_B_TO_A, STOP_CHECK, FAULT } bal_state_t; volatile bal_state_t bal_state = IDLE; void balance_task(void) { uint16_t v1 = get_batt_mv(1); uint16_t v2 = get_batt_mv(2); int32_t delta = (int32_t)v1 - v2; switch (bal_state) { case IDLE: if (delta > 20) bal_state = BALANCE_A_TO_B; else if (delta < -20) bal_state = BALANCE_B_TO_A; break; case BALANCE_A_TO_B: set_balance_direction(CELL1_TO_CELL2); enable_balancer(true); if (delta < 10 || battery_temp > 60) { enable_balancer(false); bal_state = STOP_CHECK; } break; case BALANCE_B_TO_A: set_balance_direction(CELL2_TO_CELL1); enable_balancer(true); if (delta > -10 || battery_temp > 60) { enable_balancer(false); bal_state = STOP_CHECK; } break; case STOP_CHECK: // 等待端电压稳定后再判断 if (abs(delta) < 10) bal_state = IDLE; else bal_state = (delta > 0) ? BALANCE_A_TO_B : BALANCE_B_TO_A; break; case FAULT: enable_balancer(false); break; } }这套逻辑跑起来后,整个系统给人一种“不慌不忙”的稳定感,没有明显来回切换的噪声和热波动。
3.3 浮充、放电和待机要区别对待
备用电源的使用场景不是只有一个工况,我分了几种典型状态来调均衡策略。
浮充状态:两节电池都接近满充,关键是防止过压。这时候均衡的重点是让电压高的那节稍微少充一点,把多余能量搬到低的那节。但要注意均衡电流会叠加到充电电流上,如果均衡导致整体电流超过充电器极限,反而会让电池处于持续过充状态。所以浮充时我把均衡电流限制在较小的挡位,比如 0.4A,优先保证安全。
放电状态:系统带载运行,电池电压会持续下降。这时候均衡的价值在于尽量把两节电池的剩余电量拉齐,防止其中一节先到欠压点从而拖垮整个系统。但由于放电电流本身很大,端电压波动明显,不能频繁依据瞬时压差做判断,我建议只在小电流间歇期启动均衡,大电流放电时干脆关闭均衡,等到负载结束再恢复。
长期待机状态:这是备用电源最典型的工况。电池满电挂在那里,充电器在浮充,偶尔有负载短时启动。这种状态下两节电池的差异主要来自自放电率差异,压差增速很慢,但会一点一点扩大。我用定时唤醒策略:主控平时睡在低功耗模式,每 30 分钟醒一次,采样两节电池电压,如果压差超过阈值就打开均衡,均衡 10 分钟后再次进入睡眠。这样整机平均功耗非常低,又能长期压住压差漂移。
降载处理也必须有:如果系统检测到放电电流超过设定值,说明进入了高负载工况,均衡立即暂停。因为此时均衡模块的电流会干扰电池对负载的输出能力,尤其是备用电源给小容量负载供电时,额外的均衡电流可能触发电池过流保护。
4. 储能场景下的系统联调与故障排查
4.1 实测波形与关键指标
联调阶段我把示波器探头接在均衡电感的开关节点和采样电阻两端,观察电流波形。正常工况下,开关节点是稳定的方波,频率约 300kHz,采样电阻上看到的是连续的三角波电流,峰值约 1.2A,平均电流约 0.6A。
最开始发现一个问题:均衡电流波形不是干净的三角波,而是叠加了明显的高频振荡。后来排查确定,问题出在电感和芯片引脚之间的走线太长,形成了寄生振荡。把走线缩短、加宽,同时在芯片功率脚附近增加了一颗 0.1μF 的高频电容后,波形立刻干净了。这个现象说明主动均衡电路对功率回路几何非常敏感,布局优先级高于一切。
均衡效果的测试过程也很重要。为了快速验证,我把两节电池人为充到 3.55V 和 3.50V,压差 50mV,然后启动均衡。实测经过约 25 分钟,压差降到 10mV 以内,均衡过程中电池表面温度升高不到 3℃。如果不做均衡,同样两节电池在备用电源里浮充一个月后,压差可以扩大到 120mV 以上,而且趋势还会继续恶化。
还有个值得记录的指标是均衡效率。我通过比较均衡前后两节电池各自放出的容量差来衡量,整个过程中的能量损耗主要来自电感铜损、芯片开关损耗和导通损耗,总体能量转移效率约 85%。相对被动均衡的 0% 效率,这个提升是数量级的。
4.2 常见问题速查表
调试过程中遇到的问题,我整理了一张速查表,很多问题现象相同、原因却完全不同,提前对照能省很多时间。
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 均衡电流很小或没有 | 电感饱和电流不够,电流保护误触发 | 换更大饱和电流的电感,检查电流采样电阻规格 |
| 均衡启动时 MCU 复位 | 主控供电 LDO 输入被均衡电流拉低 | 增大 LDO 输入电容,独立供电走线 |
| 电池电压读数跳变 | ADC 引脚被开关噪声干扰 | 增加 RC 滤波,采样时暂停均衡 |
| 芯片表面温度偏高 | 功率回路走线过长或电感品质差 | 缩短功率回路,换低 DCR 电感 |
| 均衡方向反复切换 | 采样时机不对,读到了带负载端电压 | 改成停止均衡后再采样 |
| 两节电池压差始终压不住 | 均衡阈值太宽或均衡时间太短 | 收紧阈值,延长最长均衡时间、提高均衡电流 |
| 外壳靠近电感处有啸叫 | 电感磁芯松动或开关频率进入可听区 | 换一体成型电感,调整开关频率 |
4.3 长期浮充测试中的特殊发现
备用电源是要一年到头挂在系统里的,跟普通测试瞬间出结果不一样,我专门做了一轮连续 30 天的浮充老化测试。 过程中发现一个有意思的现象:均衡并不是完全消除压差,而是把压差压在一个动态稳定的区间内。每天白天由于环境温度高,自放电差异大,压差会稍微涨上去,凌晨温度降下来,均衡又会把它慢慢拉回来。这种小幅波动其实是正常的,不用一看到压差超过阈值就紧张。
但有个坑必须提醒:均衡阈值不能设得太激进。我开始时把阈值设成 10mV,结果均衡模块每隔几分钟就启动一次,虽然每次工作时间不长,但频繁的大电流脉冲对电池循环寿命的影响,可能比缓慢的小压差更糟糕。后来把阈值放宽到 20mV、停止阈值 10mV,系统反而更安静,电池温度更稳定,整体效果更好。
另外一个容易忽视的是主控看门狗。PIC18LF45K50 的软件跑状态机、通信、均衡控制,任何一个环节卡死都可能让均衡使能一直保持打开,这在备电场景里是安全隐患。我的做法是:看门狗周期设为 1 秒,主循环任务必须按顺序喂狗,并且均衡使能引脚在每个主循环周期内都要被重新写一次,一旦主控跑飞,看门狗复位后引脚就会回到默认关断状态。
最终这套 2 串主动均衡方案在储能样机和备用电源负载测试中稳定运行了几个月,最明显的变化是两节电池在长期浮充后的容量差明显缩小,系统从满载到低电量报警的可用时间也比未均衡时更长。均衡这件事,重点不在于把两个电池做到绝对一样,而是让它们不至于因为一点点差异就被迫提早退休。电路和算法都不复杂,真正复杂的是把每个细节都想清楚后再动手,这也是我一直主张的做法。