做储能或者备用电源最头疼的事就是串联电池组用久了电压不齐。我手头这个小项目电池侧就是两节磷酸铁锂串联原本以为串数少不用太讲究结果容量差异越放越大最后被迫上了 MP2642GR-Z 做主动均衡再用 STM32F407VGT6 做系统主控才把均衡变成一件可控的事。下面把选型、硬件、策略、实测和踩过的坑都写下来供正在做 2S BMS、储能控制器和备用电源主控的朋友参考。1. 串联失配为什么躲不掉从“出厂一致”到“各自飞行”1.1 电芯差异不只是容量差还有内阻、自放电和温度系数很多人在做电池管理时有一个误区认为均衡只跟“容量不一致”有关。其实两节串联电芯之间的差异是复合的。容量差异决定了一次充放循环里谁先到截止电压内阻差异决定了大电流下谁先触发保护自放电差异决定了静置状态下谁的电压掉得快温度差异又会影响内阻和自放电的进程。更麻烦的是这些参数还会互相放大比如自放电大的电芯长期浮充后电压偏低充电时又因为温升慢、内阻偏高等原因表现得“很不配合”。备用电源和储能设备跟消费电子产品最大的不一样在于工况周期特别长。手机电池一天一个循环每一圈都在刷新状态差异反而被“平均化”了储能设备多数时间挂在浮充线上偶尔才深度放电一次。这时候自放电差异、极化恢复差异都在静置中被放大。我实测过一组标称容量差只有3%的电芯连续浮充28天之后两节电压差能从10毫伏拉到50毫伏以上。这不是个别现象是串联电池的必然宿命。1.2 被动均衡为什么在这种场景下“中看不中用”被动均衡的原理是把电压偏高的电芯通过并联电阻放电把能量变成热让别人“慢慢追上来”。充电末端这招确实有效能压住高电芯的电压抬头速度。但在浮充和静置为主的备用电源场景里问题就出来了系统大部分时间不在充电被动均衡要么不启动要么启动之后长时间无意义耗电。而且大电流被动均衡的发热很扎手1安培放电就是几瓦热耗局部温度上去了旁边采样电路跟着漂极易引发二次误判。更本质的短板是被动均衡永远只能“删”能量不能“补”能量。低容量电芯始终是那块短板高电芯的能量被白白烧掉整体可用容量并不会变高。我有段时间为了压住末端的电压抬头把均衡电阻功率加大结果发热问题又冒出来了后来发现这条路越走越窄不如直接换主动均衡。1.3 主动均衡的选型为什么最终交给 MP2642GR-Z主动均衡是在两个电芯之间修一条能量通道把高电芯的电荷“搬运”给低电芯像两个水池之间用水泵调水而不是把高水池的水直接放掉。原理上可以用电感、变压器、电容等拓扑实现。我一开始也想过自己搭分立方案来控制电荷泵但很快意识到一个问题均衡是“低频、长时间、精度敏感”的活对开关管时序、死区、采样噪声都很挑剔不如用一颗已经验证过的专用芯片把功率级和保护逻辑收敛掉把工程风险降到最低。MP2642GR-Z 本身就是给两节串联电池做平衡用的专用器件双向转移电荷、方向自动判断外部控制也很简单。它在整机里的角色就是“执行器”主控只需要关心策略要不要搬、搬多久、搬到什么程度。这个分工最大的好处是所有功率级层面的坑都由原厂验证过了我这边可以把精力放在系统侧的采样、保护和工况理解上。用一句话概括它把“怎么搬”解决了剩下“什么时候搬”交给我。2. MP2642GR-Z 的执行逻辑两节电池之间稳定的电荷搬运工2.1 它在整个系统里的位置整套系统的连接关系其实很简单。两节电芯串联输出给负载或充电回路MP2642GR-Z 的两个功率端口分别跨接在第一节电芯和第二节电芯两端芯片通过内部的电荷泵结构把电荷在“第一节电芯”和“第二节电芯”之间来回搬运。MCU 通过控制线决定均衡是否启动、以多大平均电流工作同时实时读取两节电芯电压、温度和整机的充放电状态。这里我特别想说清楚一个容易误解的地方均衡芯片不是把电能搬运到“整组电池”的外部负载而是只在两节电芯之间的内部环路里流动。所以均衡过程可以在静置、待机甚至系统不对外供电时执行不会干扰负载路径。对于备用电源这种长时间不充不放的场景这一点特别重要——它意味着系统闲着没事干的时候正是做均衡的黄金窗口。2.2 方向怎么判断谁高就搬谁但不是无脑搬MP2642GR-Z 这类双电芯均衡器内部会不断比较两个电芯的端电压电压高的一侧电容被充电电压低的一侧电容再放电实现电荷从高电压电芯向低电压电芯的转移。方向判断在芯片内部完成不需要 MCU 去计算“应该从Cell1搬到Cell2还是反过来”MCU 只需要授权“可以搬了”。但“无脑搬”是有风险的。电芯端电压在充放电瞬间会受到内阻压降影响放电时内阻大的电芯电压被压低得多这时候采到的“差值”是假失配。如果 MCU 不加以区分均衡器很可能在大电流放电工况下做反方向搬运。这也是为什么我在整机设计里把均衡执行权和“工况感知”绑定在一起系统只有在静置或小电流充电状态下才会授权均衡放电过程中直接锁死使能。2.3 平均电流怎么控制硬件档定峰值软件档定时间均衡电流的控制我用的是两段式思路。第一段是硬件设定通过外围元件的取值把均衡峰值电流定在一个安全区间这决定了单次启动时的最大搬运速率第二段是软件控制MCU 通过控制使能信号的工作时间比例也就是平均等效电流。比如想让均衡电流小一档不必改电路只要把使能信号从“常开”改成“开100毫秒关100毫秒”平均电流就下来了。这个策略比单纯地“通/断”要灵活得多。我的做法是电压差大时使能一直打开用接近硬件设定电流的速度快速搬运电压差接近死区时降低工作时间比例用小电流慢慢磨。软件定时器能精确到毫秒这种“峰值电流硬件定、平均电流软件调”的方式实际效果比我想象中更稳均衡末端的过冲也明显减少。提示芯片手册里的电流与参数曲线通常不是线性的不要用“占空比50%就等于电流减半”这种线性假设实测后查表处理才靠谱。3. 硬件设计STM32F407VGT6 的周边不是“接几根线”是“跟干扰抢精度”3.1 主控资源分配STM32F407VGT6 在这个项目里用的外设不多但每一样都得安排明白。片内 ADC 负责两节电芯电压和两个温度点的采样定时器负责给均衡使能线产生毫秒级时间控制UART/CAN 负责和上位机以及充电机通信。主频168MHz对这套算法来说非常富裕跑均衡状态机的循环根本用不了多少算力多出来的能力都用在滤波、日志和通信协议上了。供电上电池电压经过宽压 LDO 稳定到3.3伏给 MCU。这颗 LDO 要选静态电流小的备用电源长期待机系统自身的底电流是硬指标。我试过用普通线性稳压器静态电流上百微安放在整机里显得很浪费后来换了一颗低静态电流的 LDO整机待机电流从500微安左右降到150微安以下对长周期备电来说意义很大。3.2 电压采样均衡判断的地基两节串联电池的电压采样是这套系统里最需要花心思的地方。Cell2 电压可以直接看成“Cell2正端对Cell2负端”的电压单端采样合理但 Cell1 电压是浮在 Cell2 之上的必须做差分采样或者用“总电压减去Cell2电压”的方式间接求。我实际采用的是高精度电阻分压加运放差分放大每个采样通道都加了 RC 滤波再送到 STM32F407VGT6 的 ADC 引脚。采样精度直接决定均衡策略的生死。第一次打板时我图省事用了普通1%电阻结果分压比之间的微小误差放大到几十毫伏均衡器把“采样误差”当成了“真实失配”一直在错误方向搬运。后来统一换成低温漂精密电阻并在固件里留了一板一校准的系数表采样误差才压到3毫伏以内。如果你不想上 AFE又要保证均衡精度校准这个步骤躲不掉。采样回路的布线也要专门考虑。均衡芯片工作时功率环路上有开关电流如果采样线横穿这个环路采样引脚会看到百毫伏级的毛刺。我的处理方式是把采样线从电芯端子单独引出与均衡功率路径分开走线ADC 引脚再并联一个小电容给采样窗口提供电压保持。这些细节在原理图阶段看不出差别实测噪声却差好几倍。3.3 温度采样和保护联动锂电池均衡不能孤立工作它必须躲在“安全边界”里执行。我在每节电芯表面贴 NTC通过分压电路送 ADC一旦温度超过阈值MCU 立刻把均衡使能拉低防止安全裕量被滥用。过压欠压的判断也放在同一个保护逻辑里任一电芯电压越界均衡动作马上停止并通过通信口上报故障。这部分的经验是保护动作要“宁可保守也不要激进”特别是备用电源场景均衡本来就不是高频动作宁可让它少搬几次也不能在异常状态里硬搬。我在保护逻辑里加了延迟确认任何故障信号都会连续采样几次、持续几十毫秒才真正触发避免瞬时噪声带来的误保护。3.4 PCB 布局里的几个硬要求主动均衡板子的布局比普通控制板敏感得多以下几项是我这次画板时反复检查的点均衡芯片的功率环路面积要尽量小飞跨电容和功率路径靠近芯片放环路越小辐射越少。MCU 与均衡芯片之间的使能控制线要加下拉电阻防止 MCU 未就绪时控制端悬空。采样信号线不要与使能/PWM线平行走线开关信号上升沿非常陡串扰会把采样结果搅乱。均衡电流路径的铜宽按持续电流降额来画别只按平均电流算瞬时大电流的发热也得考虑。芯片功率区域下方铺地并且打过孔散热长时间均衡时的温升能压下去不少。这些条条框框看着是通用经验但在主动均衡板子上是真要命。均衡芯片就在采样回路旁边高频开关只要布局不干净后级软件怎么滤波都救不回来。4. 均衡策略设计什么时候搬、搬多少、什么时候停都是状态机问题4.1 状态机比“每轮ADC都拍脑袋”可靠得多均衡控制如果用“每轮采样后立刻判断要不要开”的写法很容易出现震荡电压差刚超阈值就启动搬掉几个毫伏后又停止然后极化反弹又启动整个系统就在启动和停止之间来回抖。我给这套系统写了一个四状态机待机、监测、均衡中、保护。待机态只做周期性采样监测态要求连续多次采样都超过阈值才进入均衡均衡态里周期性检查是否达到停止条件保护态只在异常时进入故障解除后还需要一个延时确认才能恢复。这样的状态机有一个额外的好处每个状态的行为都清晰可控便于日志记录。我可以从 UART/CAN 的日志里看到“什么时候进入均衡、搬了多久、什么时候停止、停止时压差是多少”这对长周期调试和故障复盘都极有帮助。4.2 死区、滞回和连续确认均衡死区我建议放在10到30毫伏之间。太小会让系统频繁启停太大则均衡效果不明显长期电压差一直挂在二三十毫伏上下。实际参数我用的方案是启动阈值20毫伏、停止阈值10毫伏。压差大于20毫伏时开启均衡压差被压回到10毫伏以下才停止。中间这段“启动快、停止慢”的滞回窗口专门用来吸收电芯极化电压和采样噪声的来回波动。还有一点容易被忽略均衡停止之后的几分钟里电芯的极化电压会慢慢恢复刚刚压低的电压差会反弹一部分。所以不要妄想“做一次平衡就永远平衡”更合理的预期是“每次均衡把压差从几十毫伏压到几个毫伏然后在长期使用中周期性重复”。我在固件里把均衡周期跟静置时间绑定每次静置超过10分钟且压差越限就自动跑一轮均衡。4.3 分档均衡粗调快搬、细调慢磨均衡电流分档是这个项目里收益最明显的策略。我按电压差大小把均衡分了三档压差大于80毫伏时使能长时间打开以接近硬件设定的电流快速搬运压差在20到80毫伏之间工作时间比例降到50%左右用中速继续搬压差低于20毫伏但高于停止阈值工作时间比例进一步降到10%到20%用很小的平均电流做末端微调。这样做的原因是如果全程用大电流搬运每次在压差接近停止阈值的临界点上都会因为采样延迟和极化恢复出现明显过冲——好好的“均衡”反而变成了“过补偿”。分档之后末端的微小压差用低平均电流处理过冲问题基本消失。这个现象和 PID 控制里的积分过冲很像本质是系统惯性和反馈延迟之间的矛盾削掉增益就好了。typedef enum { STANDBY 0, MONITOR, BALANCING, FAULT } bms_state_t; static bms_state_t state STANDBY; void bms_main_loop(void) { int16_t diff_mv get_cell_diff_mv(); switch (state) { case STANDBY: if (system_idle() diff_mv BALANCE_START_MV) { confirm_count 0; state MONITOR; } break; case MONITOR: if (diff_mv BALANCE_START_MV) { if (confirm_count 3) state BALANCING; } else { confirm_count 0; state STANDBY; } break; case BALANCING: if (diff_mv BALANCE_STOP_MV) { set_balance_enable(0); state STANDBY; } else if (diff_mv 80) { set_balance_duty(BAL_DUTY_100); /* 粗调 */ } else if (diff_mv 20) { set_balance_duty(BAL_DUTY_50); /* 中调 */ } else { set_balance_duty(BAL_DUTY_15); /* 末端细调 */ } break; case FAULT: set_balance_enable(0); break; } }4.4 与充放电工况的联动均衡不是什么时候都能开均衡是否启动必须看系统处于什么工况。充电末端电芯电压上升快均衡可以提前打开用来压住高电芯的头部电压放电过程由于内阻压降会把真实电压差搅浑我直接把使能锁死不管压差看起来多大都不搬静置和浮充阶段极化电压已经消散采样到的压差最接近真实状态是执行均衡的黄金窗口。这套“工况感知”逻辑的实现成本很低只要在状态机里加一个工况判断条件即可但对均衡效果的影响却非常大。我没有加这个逻辑之前曾经在放电过程中看着“压差”做均衡结果方向全是错的白白浪费了十几天的调试时间。后来把工况这个条件加进去几乎所有误均衡都消失了。5. 实测数据60毫伏压差收敛到5毫伏的全过程5.1 测试平台和条件测试对象是两节标称3.2伏的磷酸铁锂电芯实际容量差约3.5%。测试前把电池组充到接近满电然后静置2小时让极化电压充分消散记录起始压差。均衡过程中MCU 的 ADC 采样频率设为1千赫兹每200毫秒做一次平均后再写入日志避免单个噪声点影响判断。整个测试过程中系统不带负载相当于模拟备用电源的“静置待机”场景。这也是我前面强调过的静置状态下的压差最真实均衡效果也最能说明问题。5.2 收敛过程粗调、中调、细调各负责哪一段实测起始压差约60毫伏我直接用大档启动均衡电流接近1安培。前10分钟压差从60毫伏降到32毫伏这一段非常快因为高电芯的电荷被高速搬运到低电芯之后我切到中档25分钟时压差到14毫伏最后切到低档总耗时约35到40分钟时压差稳定在5毫伏以内。关键节点整理成表时间节点电压差mV均衡档位说明0 min60大档起始压差快速搬运10 min32大档粗调阶段结束25 min14中档中调阶段结束35 min6低档进入末端细调40 min4~5低档/停止稳定在死区以内整段均衡过程大约搬运了0.16安时电荷。对两节2.2安时的电芯来说相当于把高电芯里约7%的可用能量转移给了低电芯。这些能量如果走被动均衡就被转换成热量白白散掉了走主动均衡之后系统整体可用容量得到实实在在的提升。单次幅度虽然不大但在长期浮充电池组里这种周期性的小步搬运正是防止压差劣化的关键。5.3 效率与热表现均衡过程中的损耗就是搬运效率问题。实测在1安培大档运行时整机热耗大约在1.2到1.8瓦芯片和周边器件表面温升在30到35度左右。如果产品外壳是密闭塑料且没有风道这个热量积攒起来会很明显我建议把大档电流上限降到0.7安培左右做降额或者在PCB布局上把芯片功率区域的下层铜箔尽量完整铺地作为散热通道。这里还有一个小经验不要只看稳态温升还要看热循环。均衡启动时器件升温、停止时降温反复热循环对焊点可靠性有影响。所以我在室外或大温变场景下会刻意降低均衡运行频次让系统“一次多搬一会儿、然后长时间休息”而不是频繁短启停。6. 踩过的坑和能直接抄的作业6.1 坑一采样点接错位置搬了半天全白搬第一次联调时我看到日志里 Cell1 电压比 Cell2 高100多毫伏均衡芯片也在老实搬运但拿万用表去量电芯两端压差几乎为零。排查到最后发现问题出在采样点位置我把采样线接到了均衡路径的引线上均衡电流经过导线电阻时产生了额外压降MCU 把这段导线压降当成了电芯失配。后来把采样点改到电芯端子处单独引出问题当场消失。这个坑在原理图阶段特别好避免只需要记住一句话采样线必须从电芯端子直接引出绝不能从功率路径上分出来。被动均衡时代电流小无所谓主动均衡电流上到1安培之后导线电阻产生的压降再也不是能忽略的量级了。6.2 坑二使能被毛刺触发放电工况里乱搬还有一个印象深刻的问题大电流放电时均衡芯片的使能控制线被开关噪声毛刺触发均衡在放电工况里异常启动。均衡芯片本身并不认识“放电”这个词它只负责对压差做反应如果 MCU 没有及时把使能拉低它就会在错误时间乱搬。硬件的解决办法是在控制线上加一个下拉电阻让 MCU 未主动驱动时的默认状态为“禁止均衡”软件的解决办法是把放电工况下强制拉低使能的逻辑放在循环最前面任何人从日志里看行为都应该是“放电期间均衡绝不动作”。这类问题不大但一旦中招排查链路会非常烧时间。6.3 关于长期运行策略的一点体会几次迭代之后我对主动均衡的定位有了新的认识它不是一个“一次性修复工具”而是一个“慢变量控制器”。只要电芯的一致性差异存在均衡就要周期性运行每次都把压差压到很小但不必追求永远为零。我在固件里设置的均衡条件是“静置超过10分钟且压差超过阈值就启动”并加了单次最长运转时间防止意外情况下无限搬运。这个“细水长流”的思路在储能备电场景里特别好用比追求一次均衡彻底解决的体验好得多。6.4 后续扩展方向这套系统下一步我打算做三件事把均衡日志和诊断信息统一集成到上位机双击就能查看历史均衡事件增加充电机和负载的联动控制让均衡策略跟着整机工况走而不是孤立运行再就是考虑多串扩展把这种“单点均衡芯片加MCU策略”的架构用级联方式覆盖更多节串联电池。对于手头只是两串电池的备用电源或储能控制器这套架构的代码量和硬件难度都在可控范围内可以直接作为参考原型去改。最后关于主动均衡想再啰嗦一句个人体会它成不成的关键往往不在均衡芯片本身而在采样精度和工况判断。芯片解决的是“搬得动”策略解决的是“搬得对”后者才是真正拉开体验差距的地方。