
手里的备用电源项目从单节电芯升级到两串之后第一个让我睡不着的问题不是容量够不够而是两节电芯的电压差。实测下来同批次、同容量的两颗电芯在静置两周后能差出40~80mV充电时先到保护电压的那颗直接把我整段充电流程卡断。所以在储能和备用电源系统里给两个串联电池单元做均衡不是可选功能而是保容量、保寿命的刚需。这篇文章把我用 MP2642GR-Z 这颗均衡前端配合 STM32F303ZE 控制核心理清楚的过程完整写出来包括为什么选主动均衡、测量部分怎么处理整组8.4V的共模电压、固件里的阈值和迟滞怎么设、实测电压差怎么从50mV收敛到5mV以及调试中踩过的三类坑。1. 两个串联电芯的“不一致”为什么绕不过去1.1 电压失衡的三个来源容量差、内阻差、自放电差很多人一开始觉得“两颗电芯是同批次出厂参数一样串联用就没问题”但放到实际工况里根本不是这么回事。串联回路里电流处处相等可两节电芯对外呈现的电压却由各自的开路电压、极化内阻和当前荷电状态共同决定任何一项不一致都会在端电压上体现出来。第一个来源是容量差。我不说极端情况只按正常制造公差来算两节标称50Ah的磷酸铁锂电芯经过分容之后仍可能有±2%~3%的偏差。这意味着其中一节可能只有48.5Ah另一节有50Ah。充电时从同一起点出发容量小的那节先到充电截止电压整组被迫停止放电时又是容量小的那节先到放电截止电压整组被迫停止。每一轮充放循环这个3%左右的容量差都要牺牲掉一次而且会随着循环老化越拉越大。第二个来源是内阻差。极耳焊接工艺、连接片长度、电芯自身老化速度不同都会造成两节电芯内阻不一致。内阻差最麻烦的地方在于它不是恒定值大电流充电时内阻大的那节瞬时压降更大电压反而看着“更低”容易误导均衡判断一旦电流撤掉极化恢复真实电压又会弹回来。第三个来源是自放电差。静置状态下每节电芯的自放电率并不相同。备用电源恰恰是最典型的“长期静置偶尔大电流放电”场景电芯在浮充或离线状态下放得越久相互之间的电压差就累积得越明显。我遇到过两颗电芯静置三周后差出近100mV的情况这个量级已经完全不能靠充电结束时的短暂均衡来弥补了。1.2 失衡对储能/备电系统的实际伤害对储能和备用电源系统来说失衡的直接后果不是“某节电压高了一点”而是整套系统的可用容量和可靠性同时缩水。先说可用容量。还是按上面50Ah的例子如果均衡不动作充电结束时容量小的电芯已经到4.2V或磷酸铁锂的3.65V容量大的那节只充到约95%整组没法再充放电结束时容量小的先空容量大的还剩一点但没法用。一进一出整组实际循环容量最多只有大电芯容量的95%也就是说系统设计的8小时备电时间实际只能撑7.5小时左右。这个损失是每周、每天、每个充放周期都在发生的。再说安全与寿命。失衡累积到一定程度容量小的那节在充电时会被反复推高到过压区锂电在4.2V以上每多待一分钟正极结构和电解液界面都在加速劣化严重时可能引发安全问题放电时则是它在被反复拖拽到欠压区铜箔溶解、析锂、容量衰减都会被放大。更麻烦的是这些问题会进一步拉大电芯之间的差异形成“越失衡越加速老化”的闭环。1.3 为什么被动均衡在备电场景里不够用被动均衡是最常见的方案原理就是把高电压电芯的能量通过电阻放掉靠发热消耗掉多余电荷。很多模拟前端芯片内置了这种均衡通道。它的局限非常明显能量被白白烧掉而且只能在充电末期特别是恒压段才有意义。为什么因为被动均衡只能“泄放”不能“补充”。在充电恒压阶段高电压电芯被电阻拖住低电压电芯继续被充入两者逐渐靠近这是它的主战场。但备用电源的场景是长期浮充和静置如果高电芯是因为自放电慢才保持高电压被动均衡把这些多余能量烧掉后整组能量并没有被补到低电芯里系统总电量实际上是减少的。更糟的是离线备电时没有任何充电电流来补偿被泄放的电荷均衡本身反而在消耗电池。主动均衡的思路则是把高电芯的能量搬给低电芯通过电感或电容做能量转移效率可以做到85%~95%不依赖充电状态静置、浮充、轻载待机时都能工作。这就是我在这个2S模组项目里坚持用 MP2642GR-Z 这类主动均衡前端而不是走被动均衡通道的根本原因。2. MP2642GR-Z 与 STM32F303ZE功率前端和决策大脑怎么分工2.1 MP2642GR-Z 负责的功率均衡通道先把器件定位说清楚。MP2642GR-Z 是一颗面向双节串联电芯的主动均衡前端芯片它的核心职责是承接功率部分的开关动作和能量搬运控制。在实际电路里它配合外部电感和小型功率MOS管组成一个升降压式的能量转移通道电感的一端接在两节电芯的串联中点另一端通过两只开关分别接到整组正极和整组负极这样就能先把高电压电芯的能量励磁到电感里再释放给低电压电芯。我把这颗芯片当成功率前端来用意义在于让软件不直接参与高频开关。真正的高频PWM、死区控制、防直通、过流限制都在芯片内部或者芯片与功率器件之间完成MCU只需要告诉它“往哪个方向搬、搬多久”。这样固件里的实时性压力小很多也不用担心开关瞬间的直通风险。用这颗IC时有一点要注意它的外部功率器件选型和电感参数直接决定了均衡电流上限。如果只想跑0.3A小封装的MOS和小电感就够如果希望均衡电流到1A甚至更高就必须重新核算MOS的导通损耗、电感的饱和电流和PCB散热。不要指望一颗芯片把所有功率场景都包圆芯片只是把控制逻辑简化了。2.2 STM32F303ZE 负责的采集与决策STM32F303ZE 在这个项目里的角色是“决策大脑”。它是Cortex-M4F内核主频72MHz512KB Flash这些资源对均衡算法来说很宽裕。真正让我选它的关键点是模拟外设内部自带运算放大器、比较器和多路ADC可以在不增加太多外部器件的情况下完成电芯电压的调理、采样和阈值比较。具体到2S电池均衡任务F303ZE 要干四件事一是采集两节电芯的电压和温度二是跑滤波、标定和均衡状态机三是控制 MP2642GR-Z 的使能与方向信号四是通过UART或CAN把状态上报给整机控制器。四路ADC加DMA的采样架构可以做到双通道同时采样避免先采第一节再采第二节时由于时间差引入的电压漂移。内部的运放则用来缓冲分压后的信号减小ADC采样电容对高阻分压网络的抽取效应。有人会问处理这么点逻辑用一颗8位单片机或者低端Cortex-M0就够了为什么要上F303ZE我的考虑是冗余和扩展。储能系统的BMS往往还要管绝缘检测、接触器控制、故障录波、通信协议栈固件越写越大Flash和中断资源很快就不够。F303ZE的余量让我在调试阶段可以放心地加日志、加标定参数、加Modbus协议不用中途换平台重写一遍。2.3 为什么没有选“单芯片一体式BMS”市面上一体式电池管理芯片很多内部集成了ADC、均衡开关和通信接口寄存器配置好就能跑。我评估之后没有采用原因有三条。第一算法可定制性不够。一体式方案的均衡策略往往是固定的“电压差超过阈值就开电阻放电”或“电压差超过阈值就开启内部均衡开关”对时序窗口、迟滞策略、温度降额、以及与充电机的联动逻辑基本做不深。我们这次要的是面向备电浮充场景的自定义均衡策略自己写状态机能完全掌控细节。第二测量独立性。我希望电压采集链路和功率均衡通道是两条物理路径MCU自己采到的电压还能和均衡前端的保护结果互相校验。如果全部集成在一个芯片里一旦它内部ADC漂移整个系统就是“盲人骑瞎马”。第三供应链和失效模式可控。用两颗不同功能的芯片失效模式至少是独立的功率前端坏了MCU还能报警MCU挂了功率前端默认不动作系统也不会被主动均衡拖累。方案典型特点适合场景一体式BMS芯片集成度高、外围少消费电子、简单电池组模拟前端MCU采集交给前端、策略自己写大多数工业和储能场景本方案功率均衡前端MCU主动均衡、算法完全自定义2S小模组、备电、分布式储能单元3. 电压采集与电平适配接错这一级再好的算法都是空转3.1 2S电池端的测量范围与共模问题双节串联的电压范围常见的有两类锂离子体系是2.7~4.2V每节整组最高到8.4V磷酸铁锂体系是2.5~3.65V每节整组最高到7.3V。MCU的ADC只能接受0~3.3V的输入所以第一步必须做分压和电平适配。很多人第一直觉是“分压嘛用两个电阻把8.4V降到3.3V以内就行”但问题在共模和精度上。整组正极相对于系统地最高有8.4V中点最高4.2V你没法直接把这两点接到MCU运放的正负输入端做差分测量因为运放的输入共模范围和电源轨根本顶不住。常规做法是把两个节点分别对地用电阻分压然后通过软件做减法算出每节电芯电压。以我实际用的参数为例整组电压通道用300kΩ和100kΩ分压分压比为1/48.4V时ADC输入2.1V中点通道用200kΩ和200kΩ分压分压比为1/24.2V时ADC输入2.1V。这样两条通道的最大输入都在ADC量程一半左右留出了足够的余量也不会在小电压段浪费分辨率。这里有个非常关键的精度陷阱分压电阻必须用0.1%精度否则1%的误差在4V档就是40mV的误差你的均衡阈值设成10mV根本没有意义。我最初用1%电阻跑出来的数据两节电芯的“电压差”一直在±30mV之间跳还以为是电芯问题后来换0.1%电阻并做两点标定才稳定下来。3.2 用F303ZE内置运放做缓冲的实测做法分压之后的信号不能直接进ADC。如果ADC采样电容直接接高阻分压网络采样瞬间会从分压节点抽取电荷造成电压跌落和采样误差。这里的做法是用F303ZE内部的运算放大器做单位增益缓冲也就是跟随器。内部运放的好处是省掉外部运放芯片、简化BOM而且F303ZE的运放输出可以直接接到同芯片ADC的输入走内部连线减少外部走线引入的干扰。需留意的是内部运放也有输入失调电压典型值在1mV级别所以生产环节必须做一次两点标定把失调和增益误差存到Flash里。标定方法很简单用精密可调电源分别给测量通道加3.000V和4.200V读回ADC原始值解出offset和gain两个系数即可。ADC采样参数也要注意。F303ZE的ADC采样时间可以配置我建议设到最大档位并配合软件做“中值滤波滑动平均”。中值滤波对付开关瞬间的脉冲干扰非常有效滑动平均用来消除随机噪声。我的链路是1kSPS采样率先取5点中值再做16点滑动平均最后做EMA滤波。整套滤波下来实测电压噪声能压到±2mV以内。3.3 均衡功率级的驱动、续流与检流布置均衡功率级是整块PCB上最容易出问题的地方。MP2642GR-Z负责驱动逻辑但外部功率回路还是得自己布好。功率回路建议采用半桥拓扑高端MOS和低端MOS与电感组成Buck-Boost结构整个回路的走线要短、要宽开关环路面积要尽可能小。电感选择上我用的22µH功率电感饱和电流要大于均衡电流的2倍。如果均衡电流目标是0.6A电感饱和电流至少1.5A最好2A以上。电感饱和之后电流会瞬间飙升开关管应力暴增噪声也会从传导和辐射两条路径出来污染模拟部分。DCR尽量控制在50mΩ以内否则均衡时电感自己发热热漂移又会反过来影响旁边的采样电阻。MOS管的栅极电阻也不容忽视。驱动电阻太小开关沿太陡振铃和EMI严重驱动电阻太大开关损耗上升均衡效率下降。我在原型上调试到22Ω栅极电阻和100ns死区配合开关振铃幅度才控制住。这颗芯片内部如果有防直通逻辑仍然建议实测一下开关节点波形确认死区行为符合预期。3.4 PCB布局和检测线连接的注意事项关于电池检测线的接法我特别想强调“Kelvin连接”。采样线和功率线必须分开走从电芯正极、中点、负极分别引出细的采样线到测量电路功率线则单独接到均衡功率级。如果图省事把采样点直接焊在功率走线上均衡电流流过时会在走线电阻上产生压降轻则几十毫伏重则上百毫伏这会让固件完全误判方向。另外地线采用星形单点接地。整组电池负极作为唯一参考地模拟地、数字地、功率地在这里汇合不能在别处随意连通。功率地回路上有均衡电流的脉冲成分如果它和ADC参考地共用一段较长的走线采样结果就会被周期性拉偏。我在第一版PCB上就踩过这个坑均衡一启动ADC读出的电压立刻跳变8mV查到最后就是功率地和模拟地共用了一段接近2cm的走线。ADC输入引脚前建议加一个RC低通比如1kΩ串联加100nF并联电容截止频率约1.6kHz既能进一步滤开关噪声又不至于拖慢电压跟踪速度。分压节点对地还要加100nF的差模电容防止射频干扰在采样线上检波。4. 固件里的均衡状态机阈值、迟滞、去抖与超时4.1 电压滤波与生产的标定流程均衡算法建立在“可信的电压”之上所以固件的第一步永远是滤波和标定。标定参数在前面已经说过两个系数存到Flash后每次上电都读取并应用到采样链路。工厂里每一块板子都要单独标定不要沿用“同一批PCB共用同一组系数”的偷懒做法因为内部运放的失调是逐芯片分布的。滤波链路我用了两级中值滤波去毛刺滑动平均加EMA平噪声。EMA系数取0.1时间常数大约几十毫秒对每分钟才变化几毫伏的均衡场景完全足够。这里的原则是“噪声必须小于均衡阈值的1/5”如果阈值设10mV那么采样噪声应该压在2mV以内否则会在阈值附近反复启停。4.2 阈值、迟滞、去抖参数的设计均衡状态机本质是一个带保护条件的迟滞比较器。启动均衡不能只看瞬时电压差要连续多个周期满足条件才行。我用的参数如下表参数数值说明启动阈值10mV两节电芯电压差超过此值且方向明确停止阈值3mV迟滞避免在阈值附近频繁启停启动去抖5个周期每周期200ms连续满足才动作停止去抖20个周期停止判定更保守单次均衡超时30分钟防止异常情况下长期卡在均衡态均衡冷却时间60秒停止后强制静默利于散热和电压回稳温度窗口10~45℃超出直接禁止均衡这些参数不是拍脑袋定的而是根据系统时间常数推算出来的。电压采样每200ms一次5个周期就是1秒去抖足以滤掉瞬态的负载扰动。启动阈值10mV是因为0.1%分压电阻加两点标定之后测量系统能可靠分辨到的极限大约是3~5mV留出一倍余量才不至于误动作。停止阈值3mV看起来苛刻但配合20个周期的去抖实际不会导致频繁启停。4.3 与充电机、负载的联动逻辑均衡不该是孤立的“电压差大了就开”它必须知道系统当前处于什么状态。我的状态机里均衡启动的硬条件包括整组电流绝对值小于0.05C、两节电芯电压都在安全窗口内、温度在窗口内、没有故障标志。之所以要求低电流是因为大电流充电或放电时电芯端电压包含明显的内阻压降分量此刻测到的电压差不是真正的开路电压差均衡方向和力度都会失真。充电末期是主动均衡最容易出效果的时候。锂电池恒压段电流逐渐减小此时如果系统判定电流已经低于0.05C均衡可以切入一边用极小电流充电一边把高电芯能量往低电芯搬。但在大电流恒流段均衡必须完全禁止因为均衡电流会和充电电流在电芯上线性叠加可能把容量小的那节瞬间推过电压上限。4.4 核心状态机代码示意下面这段代码省去了外设初始化细节只保留状态机的核心骨架方便参考typedef enum { BAL_IDLE, BAL_TO_BOTTOM, /* 高电芯-低电芯 */ BAL_BLOCKED, BAL_FAULT } bal_state_t; typedef struct { float v1; float v2; float temp; float pack_current; /* 单位A */ } bms_sample_t; #define BAL_START_MV 10.0f #define BAL_STOP_MV 3.0f #define BAL_TEMP_MIN 10.0f #define BAL_TEMP_MAX 45.0f #define BAL_CURRENT_MAX 0.05f static bal_state_t bal_process(bms_sample_t *s, uint8_t *ok_counter) { bool v_ok (s-v1 3.0f) (s-v1 4.2f) (s-v2 3.0f) (s-v2 4.2f); bool t_ok (s-temp BAL_TEMP_MIN) (s-temp BAL_TEMP_MAX); bool i_ok fabsf(s-pack_current) BAL_CURRENT_MAX; float dv s-v1 - s-v2; if (!v_ok || !t_ok || !i_ok) { *ok_counter 0; return BAL_BLOCKED; } if (fabsf(dv) BAL_START_MV) { if (*ok_counter 5) { (*ok_counter); return BAL_IDLE; } /* 连续满5个周期才真正启动 */ return (dv 0.0f) ? BAL_TO_BOTTOM : BAL_BLOCKED; } /* 电压差小于停止阈值或方向为负时一律回空闲 */ if ((fabsf(dv) BAL_STOP_MV) || (dv 0.0f)) { *ok_counter 0; return BAL_IDLE; } return BAL_IDLE; }这个状态机还缺超时和冷却。实际工程中我会在进入均衡态时打一个时间戳超过30分钟强制退出并置冷却标志冷却期间不管电压差多大都不响应。方向判定上我这里只允许“高电芯给低电芯搬”反向的情况交给保护逻辑处理避免在故障状态下把能量往已经过压或异常的节点送。5. 实测收敛过程与调试中踩到的三类问题5.1 实验条件与收敛记录原型验证选的是两节10Ah磷酸铁锂电芯其中一节约9.3Ah人为制造约7%的容量偏差静置到两节电压出现明显差异后开始实验。均衡电流目标0.6A环境温度25℃。启动前实测电压为3.512V和3.461V电压差51mV。往下的记录是均衡过程中的典型数据时间(min)V1 (V)V2 (V)电压差(mV)状态03.5123.46151启动均衡53.5023.47131均衡中103.4953.47817均衡中153.4913.4829均衡中203.4893.4854接近停止阈值253.4883.4862停止进入冷却从记录能看出前10分钟电压差从51mV收敛到17mV速度很快后10分钟只从17mV收敛到2mV明显变慢。原因有两方面一是随着电压差缩小电芯端电压的非线性让同样大小的电荷转移对电压的影响变小二是如果均衡电流恒定小电压差时容易过冲我在固件里加了“目标电流随电压差线性减小”的逻辑让最后阶段变成涓流式均衡。5.2 为什么最后10mV最慢以及怎么处理主动均衡搬的是电荷量不是直接搬“电压”。电芯的dSOC/dV曲线在中段比较平缓也就是要转移相对较多的电荷端电压才会变化1mV越接近满电或空电曲线越陡同样的电荷量会让电压跳得越快。所以均衡前期看着猛、后期磨蹭是正常现象不必焦虑。如果你想缩短尾部收敛时间有两个方向一是提高尾部电流但这会加大过冲风险我建议不要这么做二是在判断依据上做文章把“电压差”和“估算荷电状态差”结合起来。对原型来说电压差已经足够说明问题但对量产产品我更推荐以荷电状态差作为均衡目标电压差只作为保护边界。这样做的好处是不受极化电压和温度影响均衡结果更符合“把两节电芯的能量拉齐”的本意。5.3 布局噪声、驱动振铃、看门狗复位三个典型坑第一类问题是ADC噪声。均衡一开始电压读数就出现±8mV级别的跳变位置在开关节点附近。排查后确认是功率走线离ADC输入走线太近辐射噪声直接耦合进了采样链路。处理办法是三层加宽采样走线和功率走线的间距到5mm以上ADC输入前加1kΩ100nF的RC低通最关键的是在固件里加入“均衡开关关断期间采样”的窗口把采样动作同步到功率开关的静默期噪声瞬间压到±2mV。第二类问题是开关节点振铃。均衡电流从0.3A调到0.8A后MOS管的漏源电压波形出现了明显振铃同时伴随轻微的啸叫。这是寄生电感和寄生电容在开关沿处谐振。解决方法是调整栅极驱动电阻从10Ω改到22Ω并在开关节点对地加了一个小型RC吸收网络。振铃消失后均衡效率也回升了几个点。功率回路的寄生参数每家PCB布局都不同这个值不要照抄必须用示波器实测去匹配。第三类问题是看门狗复位。均衡中的固件要把过程数据写入Flash日志写Flash时CPU被阻塞结果在运行日志写入那几十毫秒里喂狗超时系统反复复位。这个问题的教训是Flash写入不能和关键控制环路放在同一个阻塞流程里。我后来改成先写RAM环形缓冲再由后台任务在均衡空闲窗口把日志刷到Flash并且使用独立看门狗喂狗放在最高优先级控制循环里保证任何情况下都不会因为日志任务卡死而复位。6. 储能/备电场景里均衡要成为一个可靠功能而不是实验功能6.1 均衡窗口的管理浮充、待机、带载三种模式储能和备用电源的工况和消费电子不一样均衡窗口需要专门设计。我的做法是把系统分成三种模式。浮充模式下充电机以恒定电压顶在整组电池上此时均衡最有效率。策略是每隔一小段时间检查电压差一旦超过10mV就启动均衡直到压差低于5mV停止然后进入5分钟的观察期再决定是否继续。这样既避免均衡过度也让浮充电流有机会把低电芯补满。待机模式下系统没有充电也没有负载电芯完全靠自身静置。此时均衡可以在任意时刻启动但单次时间要缩短。我用的方案是每次最多均衡15分钟然后强制静默30分钟。静默是为了让电芯内部离子浓度重新均匀读到的电压才是真实的开路电压避免被极化电压误导。带载模式下均衡必须禁止。一旦负载启用放电电流瞬间很大两节电芯的内阻差会造成很大的瞬时电压差如果均衡逻辑还在跑会以为自己要处理一个巨大的失衡实际上只是瞬态现象。所以我在固件里用电流阈值加去抖把带载状态隔离开电流超过0.05C并且持续1秒以上均衡立刻退出。6.2 均衡电路自身的故障自检均衡是一个功率功能它自己也会坏。最常被忽略的是MOS管短路如果均衡通道的开关管击穿均衡电流可能不受控地流过电感在静置状态下把电芯能量白白耗掉。我建议固件增加一项“静态自检”均衡关闭状态下如果检测到均衡路径仍有电流流动或者两节电芯电压差以不该出现的速度变化就立即上报故障并锁死均衡。另外均衡对温度很敏感。高频连续开关30分钟后电感、MOS、芯片自身的温度都会上升。温度过高时不仅效率下降还可能损坏器件。我除了在电芯上放NTC还在电感附近加了一个热敏点超过85℃就强制停止均衡。如果板子上空间允许更推荐用PTC温控或占用一个MCU比较器通道来实时比较温度阈值这样连ADC采样周期都省了。6.3 从2S扩展到更多串联电芯的思路这篇文章围绕的是2S模组但储能系统的规模往往不止两节。扩展思路有两种。第一种是把“均衡前端MCU”做成一个标准模块每个模块管理两节电芯然后通过CAN或隔离UART级联MCU之间互相通信整组上位机统一调度。这种做法的模块化好但成本随级联数量线性上升。第二种是让这个2S方案扮演“均衡能量块”的角色配合其他均衡拓扑比如飞度电容或变压器多路输出做组间均衡。飞度电容负责整组跨串的能量搬运MP2642GR-Z模块负责串内两节电芯的精细均衡形成两级均衡架构。原型阶段先用2S跑通算法和可靠性再往更大模组上迁移是我目前比较推荐的路线。我个人调试这类均衡系统最大的体会是先解决测量可信度再谈算法策略。采样噪声压不进±2mV阈值和迟滞设计得再精巧也是空中楼阁。另一个值得早点做的动作是把均衡过程的历史趋势记录下来哪怕只是每天记几条电压差日志长期积累后你会发现它能非常直观地反映电芯老化曲线对预测备用电源的剩余寿命帮助极大。如果你正在搭自己的2S均衡原型不妨先从这三点入手0.1%分压加两点标定、星形单点接地、以及开启均衡后的逐分钟电压记录。