
前段时间做储能备电系统的电池管理模块遇到一个很典型的需求两节磷酸铁锂电芯串联组成 7.2V 电池单元在长期浮充待机的工况下两节电芯的电压会慢慢拉开系统必须主动把压差拉回来。我采用的方案是 MP2642GR-Z 负责均衡通道执行STM32F072RB 负责策略决策和故障处理。这篇就把这套方案从硬件搭建、采样校准、状态机设计到调试踩坑完整梳理一遍给正在做两串/四串小容量储能或备用电源的朋友参考。两串电芯看起来简单很多刚接触 BMS 的人会觉得“两节而已随便做个比较器就能均衡”。但实际上储能备电场景对长期可靠性的要求很高均衡策略做不好轻则容量利用率下降重则电芯过放、鼓包。下面的内容没有照抄数据手册的寄存器表而是讲清楚为什么这样做、怎么调参、调试中容易在哪里翻车希望对你有实际帮助。1. 从“两串也翻车”说起备用电源里不起眼的不一致问题1.1 两串电芯的压差从哪里来先说一个容易被低估的事实即使是出厂配组过、内阻和容量一致性很好的两节电芯在储能备电系统里跑几个月后也会出现明显的电压差。原因有几个。第一是自放电率差异。锂电芯的自放电率不是完全一致的同一批电芯也可能有千分之几的差别长期静置或浮充待机时自放电快的电芯SOC会缓慢低于另一只。第二是内阻差异电芯在循环使用中内阻增长率不同充电末期和放电末期的端电压就会表现出不同。第三是温度梯度如果两节电芯在模组里的位置不同散热条件不同充放电时的极化程度也不同这些差异最终都会累积为电压差。在普通消费电子里两串电芯用到一定时间就换掉了系统还能忍。但储能备电系统要求长期无人值守运行浮充时间可能占全寿命的90%以上这种工况会把不一致性放得很大。我用一套 5Ah 磷酸铁锂两串模组实测过新电芯初始压差只有 3mV浮充一个月后压差能到 80mV 左右最严重的时候超过 100mV。1.2 浮充待机场景下的“隐藏损耗”为什么备用电源场景对压差尤其敏感关键在于浮充和放电的判断逻辑。浮充时充电器按总电压控制两串总电压达到浮充值就停止恒流充电。如果两只电芯一个 3.70V、一个 3.55V加起来 7.25V总电压看起来正常但 3.70V 那只已经接近充电截止点3.55V 那只还没充满。充电电流会被那只高电压电芯拖累提前减小系统长期处于“一只过充、一只欠充”的折中状态。放电时更麻烦。备电系统按总电压估算剩余容量但实际容量由两只电芯中SOC最低的那只决定。高SOC那只还有电低SOC那只已经先到放电截止电压系统为了保护电芯直接切断输出。表现就是备电时间比预期短甚至刚切换过去就掉电。储能备电最怕的就是这种“虚电”用户看着电量百分比不低真到负载需要时却撑不住。长期不均衡还有个更隐蔽的危害每次都让同一只电芯承担过充或过放的压力它的容量衰减速度会越来越快反过来又拉大压差形成恶性循环。这也是我在这个项目里坚持要外加均衡功能的原因。2. 方案骨架MP2642GR-Z管均衡执行STM32F072RB管策略决策2.1 为什么不用纯硬件均衡方案非要加一颗MCU最省事的均衡做法确实是用比较器加MOS管做自触发均衡压差超过固定阈值就自动打开高电压那一侧的放电通路压差回落就关闭。这个方案在实验室里能跑通但放到储能备电系统里问题不少。比较器方案的阈值是死的没法跟随充电阶段调整。电池在浮充阶段和静置阶段的极化电压差异很大瞬时压差大不一定代表真实SOC不一致按照固定阈值触发均衡很容易“误打误撞”。另外纯硬件方案没有故障记录能力均衡管如果击穿短路系统只能眼睁睁看着电芯被放空没有任何保护手段。加一颗 STM32F072RB 之后整个系统的决策能力完全不一样。首先是可以做窗口判决连续多次采样确认压差真实存在再启动均衡避免瞬时扰动触发。其次是可以结合电芯电压区间、温度、充电阶段做条件约束只在安全范围内均衡。第三是能和充电器、负载联动检测到异常时通过GPIO拉低充电使能或者通过通信把状态上报给上位机。选 STM32F072RB 不是因为性能多强而是刚好够用。它是 M0 内核主频 48MHz带有 12 位 ADC、I2C、UART、多个定时器和独立看门狗封装尺寸和功耗对两串小模组都比较合适。128KB flash 跑均衡策略和通信协议绰绰有余价格和供货也都稳定。对于只需要均衡和不复杂保护逻辑的小系统没有必要上更高端的 MCU。2.2 两芯之间的任务切分和典型数据流MP2642GR-Z 在这套方案里承担的是“均衡执行层”的角色。它对两节串联电芯分别做电压检测内部集成均衡通道的开关驱动还能提供一些基本的保护功能比如过流、温度检测等。具体寄存器的位定义每个版本可能有差异我这里不展开抄手册实际开发时以你手里的芯片手册为准。STM32F072RB 承担的是“策略决策层”的角色。它通过 I2C 接口读取 MP2642GR-Z 上报的电压、温度和状态标志做滤波、校准和压差判断然后根据预设的均衡状态机决定打开还是关闭某一节电芯的均衡通路再把控制指令写回芯片。简单说芯片管“能不能均衡”和“怎么执行”MCU 管“该不该均衡”和“什么时候停”。典型的数据流是这样的两只电芯的采样电压先进入 MP2642GR-Z芯片内部做初步判断后通过 I2C 把原始电压和状态标志给 STM32F072RBSTM32 在软件里把原始码换算成毫伏做滤波和校准再结合温度、电压窗口和保护标志运行状态机状态机输出均衡控制位写回芯片后芯片驱动对应通道的放电 MOS 打开或关闭。整个过程大约每 200ms 循环一次均衡开启期间的采样会特殊处理后面详细讲。这里有一个很重要的设计原则MCU 不要试图绕过均衡芯片直接驱动 MOS。均衡回路涉及电池电压属于功率部分让专用芯片去控制功率开关更可靠MCU 只做逻辑判断。一旦 MCU 死机均衡芯片本身还有独立保护不会让电芯持续放电到危险状态。3. 硬件搭建从均衡电流选择到采样链路校准3.1 均衡电流取多少先算电池容量再选放电通道均衡电流是硬件设计里第一个要确定的参数它直接决定均衡时间、发热量和 PCB 走线要求。均衡的本质是把高电压/高SOC那节电芯多出来的能量以发热形式消耗掉被动均衡或者转移给低电压电芯主动均衡。对于两串小系统我倾向于做被动均衡结构简单可靠性高成本低控制逻辑也直观。主动均衡效率高但需要电感或变压器做能量转移在只有两串的模组里性价比不划算。均衡电流的工程经验值一般取 0.1C0.2C。以 5Ah 电芯为例均衡电流选 500mA1A。太小的话压差拉回来的速度很慢可能浮充一整天还没完全消除太大的话均衡电阻和 MOS 的发热量难以处理PCB 上要专门铺铜散热得不偿失。均衡时间可以用一个粗略公式估算t ≈ (ΔAh ÷ I_bal) × 3600。其中 ΔAh 是需要放掉的安时量I_bal 是均衡电流。ΔAh 怎么估一般根据实测的 OCV-SOC 曲线把电压差换算成 SOC 差再乘以电芯容量。我给一个实际例子某次压差 50mV 时我以 500mA 均衡电流放电把压差拉到 20mV 用了大约 25 分钟折合放掉约 0.21Ah。如果下次遇到相似的压差和容量配置就能估算需要的时间。不同化学体系的电芯 OCV-SOC 曲线斜率差异很大磷酸铁锂平台区平坦小 SOC 差可能只有几毫伏一旦进入曲线陡峭段几毫伏的电压差可能对应很大的容量差。所以不要硬套公式最好做一两次实测标定。在硬件上均衡通道的额定电流按 1A 设计比较稳妥。放电 MOS 的导通电阻要尽量小均衡电阻的功率余量留 1.52 倍PCB 走线宽度按 1A 载流要求计算。如果是用限流电阻而不是恒流源电阻阻值 R 和均衡电流 I_bal 的关系要按回路电压算。比如两串电芯中高电压那节当前电压 3.65V要得到 0.5A 均衡电流回路总电阻约 7.3Ω减去 MOS 导通电阻和走线电阻后选择标准阻值。注意均衡电阻上的功耗 P I²R0.5A 下 7Ω 电阻功耗约 1.75W不能直接用贴片 0805需要用大功率电阻或专门的散热焊盘。3.2 采样链路的分压、滤波与软件校准均衡阈值动不动就是 10mV、20mV 级别采样精度跟不上后面所有策略都是空中楼阁。采样链路的精度主要由三个环节决定前级分压电阻、滤波网络、模数转换的有效位数。如果直接用 MP2642GR-Z 内部采集通常它能做到较好的精度但 PCB 布局仍要注意采样走线要短尽量从电芯根部直接引线不要经过大电流回路附近。如果像我一样在 MCU 侧还保留一路独立采样做冗余那就得注意 STM32 的 12 位 ADC 在 3.3V 参考下的理论分辨率约 0.8mV/位但实际噪声、参考电压温漂和引脚串扰会把有效精度拉到 5mV 以上。因此分压电阻一定要用 1% 精度最好用 0.1%否则分压比本身就有误差。滤波网络的截止频率要压低一些。均衡 MOS 开启和关断的瞬间会产生很陡的电流变化地平面和采样线上的耦合噪声很容易把瞬时电压抬高或拉低。我会在采样点对地加 100Ω 串联电阻和 100nF 电容组成一阶低通截止频率约 16kHz再加一个 1kΩ/100nF 的滤波级把带宽限制到约 1.6kHz。对于均衡这种慢变信号采样带宽不需要高稳定优先。软件校准方面强烈建议做多点校准不要只做零点和满度两点校准。我的做法是用可编程电源给采样点分别加 2.0V、2.5V、3.0V、3.4V、3.65V、4.2V 几个标准电压每个点读 50 次取平均然后用最小二乘法做线性拟合把残差压缩到 ±3mV 以内。校准数据存在 STM32 的 Flash 里每次上电时自动校验一次。这个步骤看起来繁琐但之后调试均衡阈值时能省很多时间因为至少可以确信读到的电压不是自己骗自己。3.3 热设计均衡电阻不是随便焊一个就完事被动均衡的所有能量都以热量形式消散热设计直接决定均衡功能能不能长期稳定工作。最典型的问题是均衡电阻温漂。第一次调试时我用了普通厚膜电阻均衡半小时后电阻表面温度升到 70℃ 以上阻值明显变大均衡电流随之下降压差拉平速度越来越慢。后来换成低温漂的电流检测电阻并在 PCB 上加宽焊盘散热问题才解决。如果你用恒流源方案而不是固定电阻限流对电阻的要求会低一些但还是要注意散热。均衡电阻的位置也有讲究。离 MCU 过近热辐射会把主控芯片温度抬高影响 ADC 参考电压稳定性离电压基准过近基准电压漂移会导致采样值跟着漂。我在布局时把所有均衡发热器件放在板边电池采样和 MCU 放在另一侧中间留出至少 5mm 间距需要时开散热槽。另外要考虑 MOS 的散热。500mA 均衡电流下一颗导通电阻 20mΩ 的 MOS 功耗只有 5mW看起来微不足道。但选型不当导致导通电阻异常或者 MOS 驱动电压不足导致不完全导通功耗会迅速上升。我遇到过驱动电平只有 2V、选了一颗 Vgs 阈值偏高的 MOS结果它工作在放大区发热很大。后来换成逻辑电平驱动的 MOS并且让 MP2642 的驱动电路保证栅极电压足够才算稳定。4. 软件状态机让均衡在“该动的时候动该停的时候停”4.1 阈值、回差与判决窗口的整定均衡启动阈值、停止阈值和回差这三个参数是软件策略的核心。定得太小噪声和瞬态电压会让均衡频繁启停定得太大均衡功能形同虚设。我在这套系统里默认设置是压差超过 30mV 启动均衡压差降到 15mV 以下停止均衡中间 1530mV 是滞回区。为什么不是压差回到 0 才停因为采样精度和电芯极化都有限把目标定在绝对零差会永远达不到还会反复触发电均衡反而消耗电芯寿命。滞回区的作用就是防止状态机在阈值附近来回跳动。除了压差阈值还要判断绝对电压窗口。均衡只允许在电芯电压处于 3.0V3.65V 区间时进行。为什么需要这个条件如果一只电芯已经是 2.9V另一只 3.0V压差只有 100mV但此时均衡会让高电压电芯继续放电可能把两只都推向过放。电芯极化电压大的时候尤其危险看似电压还有余量去掉负载后电压可能跌到比保护点还低。另一个细节是判决窗口。我不用单次采样值做启动判断而是连续读取 5 次每次间隔 200ms5 次压差都超过启动阈值才进入均衡。这个设计是为了排除脉冲负载和模拟前端瞬态干扰。单次采样值不可信窗口判定后的结果才值得作为动作依据。4.2 状态机设计和异常分支处理状态机我分成三个主状态IDLE、BALANCING、FAULT外加一个均衡暂停分支。IDLE 状态下系统周期性执行采样和判决。条件满足就进入 BALANCING同时记录启动时间戳。BALANCING 状态下每隔 200ms 读取一次电压每 1 秒更新一次滤波值。如果压差降到停止阈值回到 IDLE如果温度超过 45℃ 或低于 0℃暂停均衡进入一个短延时等待条件恢复如果电芯电压低于过放保护点直接进入 FAULT。FAULT 状态必须锁存。所有均衡通道强制关闭设置故障标志通过 UART 上报给上位机或触摸屏并拉低充电使能信号。故障清除不能靠系统自己恢复必须由上位机下发清除指令或者人工断电重启后才复位。为什么这样设计因为均衡回路如果出现 MOS 短路、采样链路失效这类硬件故障自动复位只会让系统反复进入危险状态。锁存故障是让维护人员知道“这里出事了需要检查”。还有一个很容易漏掉的设计最大均衡时间。正常情况下压差会在 12 小时内拉回但万一均衡通道控制失效MOS 一直导通电芯会持续放电到过放。我设置了单次均衡最长时间为 240 分钟超过后强制关闭均衡通道并把“均衡超时”事件记入日志。第二天再次尝试时如果压差仍然很大可能就是均衡通道本身有问题应该进入异常计数连到三次就锁存 FAULT。下面是一段示意性的状态机代码实际项目里可以根据自己的编码风格改写typedef enum { BALANCE_IDLE, BALANCE_RUNNING, BALANCE_PAUSED, BALANCE_FAULT } balance_state_t; static balance_state_t bal_state; void balance_task(void) { uint16_t v1, v2; int32_t diff_mv; read_cell_voltages(v1, v2); diff_mv abs((int32_t)v1 - v2); switch (bal_state) { case BALANCE_IDLE: if (diff_mv BAL_START_THRESHOLD_MV battery_voltage_ok(v1, v2) temperature_ok()) { enable_balance_channel(pick_higher_cell(v1, v2)); bal_state BALANCE_RUNNING; bal_start_tick get_tick(); } break; case BALANCE_RUNNING: if (diff_mv BAL_STOP_THRESHOLD_MV) { disable_balance_channel(); bal_state BALANCE_IDLE; } else if (!temperature_ok()) { disable_balance_channel(); bal_state BALANCE_PAUSED; } else if (get_tick() - bal_start_tick BAL_MAX_TIME_MS) { disable_balance_channel(); record_event(EVENT_BAL_TIMEOUT); bal_state BALANCE_FAULT; } break; case BALANCE_PAUSED: if (temperature_ok()) { enable_balance_channel(pick_higher_cell(v1, v2)); bal_state BALANCE_RUNNING; } break; case BALANCE_FAULT: disable_balance_channel(); break; } }这段代码的核心思想是每个状态转移都有明确的条件一旦进入 FAULT 就只许出不许自动恢复。实际项目中还需要加上均衡电流闭环控制和故障计数这里只展示主干逻辑。5. 实测调试记录三个让我花了不少时间的问题5.1 采样值在均衡开启瞬间乱跳第一次联调时遇到一个很头疼的现象均衡 MOS 一打开MCU 读到的电芯电压就出现几百毫伏的跳变压差信号反而不降反升状态机以为压差又变大了于是关闭均衡。关闭后电压读数恢复正常系统又以为压差还在再次打开均衡。结果就是均衡反复振荡电芯压差几乎不动。定位过程比较曲折。先怀疑是 ADC 采样时序问题调整了采样保持时间没有改善。又怀疑是 I2C 读取频率不够于是把采样循环提高还是不行。最后用示波器抓均衡回路和采样参考地的波形发现 MOS 开启瞬间地平面有约 150mV 的脉冲尖峰而采样参考地恰好和均衡回路的地共用了一段走线。正是这段共地阻抗把开关噪声灌进了采样链路。解决思路分两步。硬件上把采样地单独走线从电芯负极根部引出不再和均衡电流回路共用低阻抗路径。软件上调整采样时刻均衡开启后先等 30ms让电流稳定后再采样并且滤波策略改用“中值 平均值”组合。这个问题的教训是均衡系统里采样地和大电流地必须分开布局这不是可选项而是必选项。如果你在调试中也遇到均衡一开电压就跳先查地线别急着改软件滤波参数。5.2 均衡电阻的温漂把我“骗”了一次均衡功能跑通之后我发现均衡速率比理论上慢很多。本来 500mA 均衡电流应该能较快拉回压差实际上均衡半小时后压差下降速度明显变慢甚至停滞。起初以为是电芯极化问题后来又怀疑是均衡回路接触不良。用钳流表实际测量均衡电流才发现电流从开机时的 500mA 慢慢掉到了 380mA 左右。摸一下均衡电阻烫得厉害。原因是那颗普通厚膜电阻温度升高后阻值变大在固定电压下电流自然下降均衡功率越来越小。解决方法是把限流电阻换成低温漂的功率电阻并且把均衡电流设计成闭环控制在均衡回路里串联一颗毫欧级采样电阻通过 STM32 的 ADC 实时读取电流用一个简单的比例调节控制 MOS 的开关频率或线性区驱动电压把电流稳定在设定值。这里多说一句如果选恒流方案硬件复杂度会增加但效果确实值得。对于 0.5A 级别的均衡电流只需要一个运放和几颗电阻就能搭出压控恒流源。均衡电流稳定后均衡时间就可以比较准确地预估策略里的超时保护也更可信。5.3 采样线布长之后均衡电流管不住第二版硬件为了布局方便把电芯采样线从电池端拉到主板长度接近 8cm。刚开始没在意后来发现一个诡异现象均衡电流越大读到的高电压电芯电压越低低电压电芯电压却有点升高压差计算总是偏差。这根采样线本身电阻很小只有几十毫欧为什么会影响读数关键是采样线走线和均衡电流路径形成了共享阻抗回路。均衡电流流过地线和采样线时在采样线上产生了额外压降这个压降和电芯真实电压叠加在一起MCU 读到的是“被污染的电压”。尤其当均衡电流达到 1A 时就算只有 20mΩ 的共享阻抗也会造成 20mV 误差这已经比停止阈值还大了。解决方式是做开尔文连接。电压采样线必须直接从电芯两极单独引出不要与均衡电流路径共用任何导体。如果必须走一段距离采样线采用差分走线两个信号线紧贴在一起减少环路面积。在电芯根部靠近采样点的地方加 100Ω 100nF 滤波也能有效减轻高频干扰。这是被动均衡系统里最常见的 PCB 布局陷阱。很多初学者把采样线接到均衡电阻下边看起来省事实际上把采样点和电流路径混在一起了。每次调试都以为均衡策略不对其实硬件就已经错了。6. 保护与备电场景下的功耗控制6.1 均衡超时保护和故障联动备用电源系统的特点是长期无人值守均衡功能不能成为新的故障源。除了前面提到的均衡超时锁存还要设计每日均衡总时长限制和均衡次数异常检测。我在这套系统里设置了每天最大均衡总时长 8 小时超过后当天不再允许启动均衡第二天零点自动复位统计。如果连续三天都出现“当日均衡时长接近上限”的情况说明电芯一致性明显恶化系统会上报提示建议人工检查和更换电芯。故障联动方面均衡通道出现异常时不能只是自己记录还要和外部设备交互。比如检测到均衡 MOS 短路充电使能信号必须下拉到无效电平否则充电器会继续给已经存在内部短路的系统充电风险很大。STM32F072RB 的 GPIO 可以直接控制一个低边开关或继电器把充电回路断开。通信接口采用 UART 或 CAN 上报故障码上位机可以定位到具体哪一个均衡通道出了问题。另一个容易被忽略的保护是异常电压检测。如果两节电芯的电压差在均衡未开启时突然从 20mV 跳到 200mV这是电芯内部异常的信号。此时系统应当进入告警状态而不是尝试用均衡去“纠正”。均衡是针对一致性问题的不是用来掩盖电芯故障的。6.2 把待机功耗压下来的几条措施备用电源大多时间处于浮充待机状态系统待机功耗直接关系到整体效率甚至温升。均衡功能本身工作时不吝啬功耗但空闲时必须把功耗压到尽量低。STM32F072RB 支持多种低功耗模式配合外部唤醒可以做到整体待机电流在微安级到几十微安级。但前提是外设不能偷电。我习惯把均衡芯片的供电也做成可控的待机时完全断电只在需要采样和均衡时才上电。采样分压网络如果一直挂在电芯两端也会产生持续的漏电流虽然只有几百微安但长期下来不可忽视。可以在采样链路上串一个低功耗 MOS 开关采样时打开采样结束关断。通信接口同样要处理。UART 或 CAN 在待机时如果持续监听功耗不小。我采用的策略是主控定时唤醒主动上报一次心跳数据平时进入收发休眠。上位机如果要下发指令先通过一个唤醒来触发主控进入接收模式。这套握手逻辑虽然多花了一点软件功夫但待机功耗能控制到 1mA 以下。均衡芯片本身的静态功耗也要关注。选型时就查清楚芯片在非均衡状态下的静态电流如果数据手册上写着几十微安那还好如果达到毫安级就必须考虑在空闲时把芯片电源彻底切断。MP2642GR-Z 这类均衡控制芯片通常有空闲低功耗模式具体配置看手册设计电路时最好留出切断电源的 MOS 开关作为备选方案。最后再分享一点体会两串电芯的均衡从原理上不复杂但把采样精度、阈值回差、热设计和故障保护串起来之后细节一点都不少。我做这个小系统最大的感受是均衡不是要让两节电压差变成 0而是把它控制在一个不会伤害电池的窗口里。如果你也在做类似的储能备电线项目建议先把采样链路和阈值回差调明白再考虑均衡电流要不要加大顺序反了大概率会来回折腾。