1. 方案选型与整体架构1.1 两节串联电芯为什么会失衡做储能、备用电源这类系统两节电池串联是最常见的电池组形态之一。很多人觉得两个电芯串联很简单电压翻倍就行但真正跑起来之后问题往往就藏在“串联”这两个字里。两个电芯出厂时容量可能一致但实际使用中每一节的内阻、自放电率、温度系数都不可能完全相同。哪怕只有微小差异经过反复的充放电循环差异会被放大。比如某次放电中容量偏低的那节电压先跌到保护阈值系统为了保护它只能停止放电于是另外一节明明还有余量整个电池组却用不了了。反过来充电时容量偏低那节先到达满充电压系统停止充电另一节又没法充满。这种“一拖全组”的效应是所有串联电池组的通病。我见过不少备用电源项目蓄电池组常年浮充表面上总电压显示正常实际上其中一节已经亏电等到真正断电需要它顶上的时候电池组容量掉得厉害甚至直接失效。问题不是单体不行而是平衡没做。想要让2S电池组真正可靠均衡电路几乎是必需品。1.2 MP2642GR-Z 和 STM32F767ZI 各自负责什么这套方案里MP2642GR-Z 与 STM32F767ZI 的分工非常明确一个管能量一个管决策。MP2642GR-Z 在系统中承担的是“受控能量搬运”的工作。它本质上是一个高效率开关电源转换器配合外围电感、电容和采样电阻可以搭成一个可编程限压、限流的电源通道。均衡的本质就是通过这个通道把能量从电压高的电芯搬出来灌进电压低的电芯让两者往中间值靠拢。STM32F767ZI 则扮演控制核心的角色。它负责采集两节电芯的电压、电流、温度判断当前系统处于什么状态决定要不要均衡、往哪个方向均衡、均衡电流设多大同时还要处理过压、欠压、过流、过温这些异常情况。F767 这颗芯片在 STM32 家族里算性能比较充裕的双精度浮点、大量定时器、多个 ADC 通道用在这里有点“大材小用”但好处是代码写起来不用抠资源后续要加通信协议、加记录功能都有余量。这两个角色组合起来相当于一个“电源执行器”加一个“大脑”。执行器不需要聪明但它要可靠、响应快大脑不需要力气大但它要能判断、能统筹。这个搭配在嵌入式系统里是很典型的闭环控制结构。1.3 方案对比为什么不用被动均衡做2S电池均衡最省事的方案其实是被动均衡——在每个电芯旁边并联一个放电电阻电压高的那节通过电阻把多余能量以热量形式放掉。成本低、电路简单、单片机只需要控制MOS开关。但被动均衡有两个硬伤。第一是效率问题能量没有被转移而是变成热量。本来电池容量就不够还在白白浪费在储能和备用电源场景里很难接受。第二是均衡能力弱放电电流受限于电阻功耗通常只能做到几十毫安到两三百毫安。如果两节电芯压差大靠这么点电流均衡可能要好几个小时甚至一整晚在应急场合完全来不及。主动均衡则不同。它通过功率变换电路把高电芯的能量转移到低电芯理论上效率能到80%~90%能量不浪费均衡速度还快。一个设计合理的主动均衡器均衡电流可以做到1A甚至更高几分钟内就能把压差拉到几十毫伏以内。MP2642GR-Z 就是为这种功率变换场景准备的配合 STM32 做数字控制既保住了效率也能做到精准可控。当然主动均衡的硬件复杂度明显高于被动均衡这恰恰是这篇文章想讲清楚的事情。2. 硬件电路里的关键细节2.1 主功率拓扑可编程恒流源加开关切换我在这个项目里用的均衡架构比较务实MP2642GR-Z 配置成一个可编程限压、限流的直流电源输出端通过两个低阻开关选择连接到 Cell1 或 Cell2。STM32 检测到哪节电压低就把输出切到那一节以恒定电流给它充电哪节电压高就切到另一侧把它当作放电对象来补充能量。你可能要问为什么明明叫“均衡”却像是在给单节充电因为对于两节串联系统给低的那节补充充电能量自然来自高电芯所在的整个电池组。当低电芯电压上升、高电芯电压下降两者的差值就缩小了。再加上控制算法里设置合理的滞回区间均衡过程就能平稳收敛不会来回振荡。这个拓扑的好处在于功率路径是单向的不需要像双向同步Buck-Boost那样处理复杂的换向逻辑。MP2642GR-Z 始终工作在它最擅长的模式可靠性高调试难度小。缺点是需要外加切换开关不过用P-MOS加N-MOS组成推挽开关成本并不高。如果拆开细看充电回路里还需要一个防倒灌措施。均衡结束后MOS 关断电芯电压可能高于 MP2642 输出端电流反过来灌进 DC-DC 输出电容容易造成电容过压或器件损伤。所以在输出路径上串联一个低压降的肖特基二极管或者在控制逻辑里确保 MP2642 输出电压始终不低于目标电芯电压这两件事至少做到一个。2.2 电压采样别让测量误差吃掉均衡精度均衡做得好不好首先取决于电压测不准不准。STM32F767ZI 内置的 ADC 是 12 位的理论上可以分辨出毫伏级别的电压变化但实际电路接入方式不对精度会大打折扣。我踩过最典型的坑直接用电线从电芯端子引到单片机引脚中间不做过任何处理。电芯在均衡电流较大时端电压会有一个明显压降采样到的电压并不是电芯真实的开路电压。而均衡恰恰需要基于电芯的极化状态去判断这个误差会直接影响均衡结果。正确做法是采用开尔文接法即采样线独立于功率线。充电电流走粗线采样线单独从电芯端子上引出经过RC滤波器再进 ADC。RC 的截止频率一般设在几百赫兹到几千赫兹之间既能滤掉开关噪声又不会挡住慢变的电芯电压信号。这里我常用的是一个 10kΩ 电阻加一个 100nF 电容时间常数1毫秒左右适合低频采样。另一个问题是串联电池组的共模电压。Cell1 的负极是系统地但是 Cell1 的正极对地电压已经接近一节的电压Cell2 更是浮在高电位上。如果用普通分压电阻把 Cell2 采进来分压比的精度会影响最终结果。我是直接用高精度电阻分压再配合运放跟随地线单独引回单片机。分压电阻选 0.1% 精度的低温漂型号长期运行才不会有几毫伏的漂移。2.3 电流采样与控制环路恒流充电必须有电流反馈。最简单的方式是在功率回路里串一个毫欧级采样电阻比如 10mΩ 的合金电阻通过的均衡电流按 0.5A 算压降只有 5mV。这个信号太小直接进 ADC 不现实需要差分放大器放大到 ADC 适合的范围内。我选的放大倍数是 50 倍左右0.5A 对应 250mV满量程约 1A 时正好接近 ADC 参考电压的一半精度有保障。采样电阻的位置也有讲究。放在 MP2642 输出负端和高电芯负极之间参考地相对稳定差分信号共模电压低放大器的选型压力小很多。放在输出正端不是不行但共模电压会随着均衡目标不同而改变很容易踩到运放共模输入范围的上限。电流环路的调节策略我在软件里用了一个简易的 PI 控制器。目标电流设定好之后实时测量电流PI 输出调整 MP2642 的反馈参考值。这个环路的响应速度不需要太快几十毫秒级别就可以因为电芯的电压变化是慢变量电流环路调得太快反而容易引入噪声。2.4 保护电路设计做电源产品保护电路不是可选项是必选项。我在这个系统里设计了四重保护输入过压保护、输出过流保护、电芯过压保护和温度保护。输入过压保护针对的是系统总电压异常升高比如充电器故障直接通过比较器检测总电压超过阈值就切断均衡路径并置故障标志。输出过流保护依赖电流采样硬件上用比较器做的快速限流不依赖软件响应时间压到微秒级。电芯过压保护则是在软件里持续监控每节电芯电压一旦超过满充电压立刻停止均衡防止把电芯充坏。温度保护是容易被忽略的但功率电路长时间工作后温度会上升我在 MOS 管附近和电芯表面各放了一个 NTC 热敏电阻读数超过阈值就降额或暂停均衡。3. 控制软件与均衡算法实现3.1 均衡判据不是有压差就均衡很多初做均衡的人会有一个误区看到两节电芯有压差就启动均衡结果电芯电压稍微波动均衡就在启动和停止之间反复横跳。均衡执行机构是功率电路频繁通断容易产生电磁干扰MOS 开关也容易发热。我用的判据是压差超过启动阈值比如 20mV才进入均衡当压差回落到 8mV 以下停止均衡。这两个阈值之间形成一个滞回区间防止反复开关。8mV 到 20mV 之间是盲区系统不动作。这个“不动”其实很重要因为电芯本身有自恢复特性很多压差其实是极化造成的假象过一会儿自己就恢复了。代码实现上我维护了一个简单的状态机每个控制周期100ms读取电压滤波后计算压差再根据当前状态决定动作。typedef enum { BALANCE_IDLE, BALANCE_CHARGING_LOW, BALANCE_FAULT } balance_state_t; typedef struct { float cell1_voltage; float cell2_voltage; float balance_current; uint8_t mos_switch; } balance_context_t; #define BALANCE_START_THRESHOLD_MV 20.0f #define BALANCE_STOP_THRESHOLD_MV 8.0f #define BALANCE_TARGET_CURRENT_MA 500.0f void balance_control_loop(balance_context_t *ctx) { float delta ctx-cell1_voltage - ctx-cell2_voltage; switch (ctx-state) { case BALANCE_IDLE: if (delta BALANCE_START_THRESHOLD_MV) { ctx-mos_switch SWITCH_CELL2; // 给电池2充电 ctx-state BALANCE_CHARGING_LOW; } else if (delta -BALANCE_START_THRESHOLD_MV) { ctx-mos_switch SWITCH_CELL1; // 给电池1充电 ctx-state BALANCE_CHARGING_LOW; } break; case BALANCE_CHARGING_LOW: if (fabsf(delta) BALANCE_STOP_THRESHOLD_MV) { ctx-mos_switch SWITCH_NONE; ctx-state BALANCE_IDLE; } break; case BALANCE_FAULT: ctx-mos_switch SWITCH_NONE; break; } }这段代码看起来简单但里面有一个关键点每次进入均衡后电流目标值并不是一步到位而是用斜坡方式逐渐加到设定值。如果直接满电流启动电感会发出明显的“吱”声开关管电流应力也大。斜坡时间设置在 50ms 左右体感上会平顺很多。3.2 电压滤波与动态响应电芯电压采样值直接拿来做控制会有很多毛刺。均衡电流本身会带来电压波动ADC 采样时序和 PWM 开关时刻重叠时噪声也会被叠加进来。我用的是“先滑窗平均再一阶低通”的二级滤波。滑窗取最近8次采样求平均用来滤掉高频噪声一阶低通的系数根据响应时间要求调整我一般取 0.8 左右对应约 200ms 的有效时间常数。#define ADC_SAMPLE_TIMES 8 #define FILTER_ALPHA 0.8f static float voltage_lowpass(float new_sample, float old_filtered) { return FILTER_ALPHA * new_sample (1.0f - FILTER_ALPHA) * old_filtered; }滤波系数太大响应慢均衡过程中电压已经真实变化了控制跟不上太小噪声进得去滞回区间的效果被破坏。你需要根据实际系统的噪声水平去调这个系数。在调试时我用一个直流电源模拟电池电压故意加入高频纹波通过串口把滤波前后的波形打出来观察这个方法效率很高。3.3 SOC修正与均衡方向判断单看电压判断均衡方向比较粗暴但大多数场景够用。不过有一种情况容易翻车电芯处于充电极化状态高电压并不代表高容量。为了避免这种误判我在软件里加入了一个简单的SOC参考——用开路电压法加安时积分估算SOC作为均衡方向的辅助判断。具体做法是系统空闲且电流接近0时记录两节电芯电压查OCV-SOC对照表得到各自的SOC百分比。均衡时参考这个SOC而不是只看瞬态电压。如果 SOC 相差超过 2%就启动均衡电压滞回阈值仍然保留但优先级低于 SOC 判断。实际项目里备用电源的大部分时间处于浮充状态电流很小OCV 估算的可信度很高。而储能系统有充放电周期安时积分漂移需要定期校准我会在电芯进入静置状态时用OCV法校准一次保证 SOC 数据长期不跑偏。3.4 与上位机的数据交互如果这个均衡控制器只在自己的小盒子里工作不往外通讯调试和维护都不方便。我预留了一路 UART后面在调试工具里也汇总了命令格式。通信协议不用复杂一个帧头、命令字、数据段、校验和。我习惯用 CRC8 做校验数据量小计算量低。上位机可以实时读到电压、温度、均衡电流、状态机状态也能下发均衡使能、目标电流这些参数。实际调试的时候能一边看波形一边下发指令效率比盲调高太多了。4. 调试过程与实测数据4.1 上电前的检查清单焊完板子先别急着插电池。我给自己列了一份检查清单每一条都踩过代价先看电源树MP2642 的输入电压范围是否覆盖电池组最高电压。两组串联磷酸铁锂满电约 7.2V供电路径上的电容耐压按 16V 选留足余量。然后检查整个功率路径有没有直接短路用万用表蜂鸣档测一下输入正负极确认不响再继续。采样通道的检查也马虎不得分压电阻的实际阻值和设计时是否一致用精密万用表逐个量0.1% 的电阻也可能虚标。接着是运放输出在没接电池的静态状态下输出应该接近0V如果偏离几十毫伏先查偏置电流和失调电压排除运放选型问题。最后检查控制信号用逻辑分析仪看 MOS 驱动波形确认没有两个管子同时导通的情况。同时导通意味着桥臂直通轻则电感饱和重则炸管。如果是自举驱动还要确认自举电容充电时间足够。4.2 电压采样的校准STM32 的 ADC 有偏移误差和增益误差直接读出来的数值需要校准。我的校准方法非常接地气用一节稳压电源或者精度高的电池先采一个已知电压比如 3.300V记下 ADC 原始值再采一个不同的已知电压比如 4.000V记第二个点。两个点拟合出 y kx b 的直线把斜率和偏移量写进 Flash每次启动时加载。如果只校准一个点斜率默认按理想值算偏差在小电压段可能不明显但采集 7.2V 端电压时误差会被放大影响过压保护的触发点。所以两个点校准是必须的我在批量件上测试过校准后的误差能控制在 ±3mV 以内。4.3 均衡效果实测我搭了一套实验环境两节磷酸铁锂电芯额定容量 2Ah一节先放电到 3.28V另一节停在 3.31V初始压差 30mV。环境温度 25 摄氏度均衡目标电流 500mA。实测过程记录如下系统检测到压差超过启动阈值切换开关给低电芯充电。前 5 分钟低电芯电压从 3.28V 升到 3.295V高电芯电压基本没变化因为它只是被拖累了少量放电。第 15 分钟压差缩小到 12mV 左右。到第 28 分钟压差降到 7mV系统按滞回阈值停止均衡。最终结果均衡结束后静置 10 分钟两节电压差恢复到 3mV 以内。整个过程的能量转移到效率约只有 87%主要还是开关损耗和线路阻抗损耗对于这个功率等级来说已经比被动均衡的“零效率”好太多了。4.4 波形观察与环路调整调试时我最喜欢看三个位置MP2642 开关节点SW波形、电感电流波形、输出电流采样波形。SW 波形的占空比和频率能直接反映调节环路是否稳定如果出现相邻周期占空比跳变明显说明环路增益过高适当减小 PI 的 P 系数。电感电流波形能看出是否进入断续模式轻载时电流波形出现“台阶”说明在 DCM 和 CCM 之间切换这是正常的不影响均衡。电流采样波形如果有过冲多半是采样电阻的寄生电感带来的需要并联高频电容来抑制。5. 常见问题与排查技巧5.1 均衡电流一直在抖动稳不住这个现象我在第一版硬件上遇到过。排查链路是这样的先看电流采样波形发现上面叠加了明显的高频毛刺。因为采样电阻到运放的走线比较长而且和功率MOS的开关节点靠太近耦合了开关噪声。解决办法有两个一是把采样线的走线改为差分方式紧贴着走并在运放输入端加一个低通RC滤波截止频率设在几十千赫兹二是在软件里降低电流环的带宽让 PI 控制周期从 10ms 放宽到 50ms环路的抗噪声能力立刻强了许多。电流波形最终稳定在目标值 ±10mA 以内。5.2 ADC 采样值跳变电压读数乱飘如果滤波算法没问题ADC 读数还乱飘十有八九是采样时刻和开关噪声撞上了。我在最开始是自由运行 ADC随意转换采到的值忽高忽低。后来改成定时器触发采样把采样时刻设置到 PWM 关断区间中段躲开开关边沿的尖峰数值立刻清透了。另一个细节是 MCU 的 VREF 引脚要用低阻抗电源供电最好加一个 100nF 和 10uF 的电容组合。VREF 上有纹波ADC 的量化基准就不稳测什么都白搭。5.3 MP2642 温度偏高均衡电流 500mA 时MP2642 的温升大概在 30 到 40 摄氏度手摸温温的属于正常。温度偏高通常是散热不够或者开关频率设置过高。我在调试时把关断频率从 1MHz 降到 500kHz开关损耗明显下降电感体积只是略微增大但温度降了快 10 度。如果芯片底部有散热焊盘一定要保证 PCB 上有连续的铜皮和过孔阵列把热量导到背面的铺铜上。我见过很多板子散热焊盘没打孔芯片热得烫手加一排过孔之后温度立刻低了 8 度。5.4 均衡效果很差压差降不下来压差一直不降先排除判断方向颠倒的乌龙开关切错了通道给高电压的电池充电越充压差越大。这种问题在模拟阶段不容易发现一旦接上真电池马上就现形。我当时是用插座跳线做切换的排查时就靠万用表量 MOS 导通后的输出端是接在哪一节上确认无误再放行。还有一个隐蔽原因MP2642 的输出电压被限制得比目标电池电压还低充电电流几乎为零。虽然设置了 500mA 目标电流但电压环更早触发限压内部环路跳过了电流环导致输出一直在电压阈值以下。解决办法是设置输出电压上限比最高电芯电压多 100mV给电流环一个足够的活动空间。5.5 常见问题速查表故障现象可能原因排查手段解决措施均衡电流抖动采样噪声、环路增益过高示波器测电流采样点差分走线、降低环路带宽ADC 读数飘采样时刻与开关噪声重叠调整采样触发时序定时器触发躲开开关边沿芯片过热开关频率过高、散热不良热成像仪、手感判断降频、补散热过孔压差不降反升开关切换方向错误万用表测通路修正切换逻辑均衡启动失败输出电压限幅过低读 MP2642 配置寄存器放宽电压上限通信偶发错误信号线受开关噪声干扰分析仪抓帧加滤波、降波特率6. 一点现场经验与扩展思路按我个人的习惯做完一个项目会把“如果重做一次哪里会改”记下来。这个方案如果再改版我大概率会把 MP2642 的配置接口用上让它完全受控于 STM32去掉手调的反馈电阻网络。这样目标电压和电流可以直接通过寄存器写入硬件上少两颗电阻调试时参数修改也不用焊来焊去。另外2S 系统里常见的充电管理也就是系统充放电共用一条路径的场景可以在均衡逻辑里加入“充电暂停时均衡、放电时均衡暂停”的协调策略实测下来对系统稳定性有帮助。两节电池的均衡是整个电池管理系统的一个基础子集。你现在模拟好这套主动均衡方案后续扩展到更多节串联时会发现核心思想是一样的能量从高处搬到低处只是切换开关数量和拓扑结构要做相应调整。这就是底层的通用逻辑。在储能和备用电源这类对可靠性要求高的场景里均衡电路不能做成玩具更不能做成摆设。一个真正能自动收敛、保护完善、调试透明的均衡控制器才是系统长期稳定运行的有力保障。希望这篇文章能给正在调 2S 均衡方案的朋友提供一些参考。