基于MP2642GR-Z与STM32L073RZ的两串电池主动均衡方案设计与实现
1. 为什么两串电池组必须做主动均衡两串电池单元串联使用是储能和备用电源系统里最常见的基础拓扑之一。无论是小型光伏储能包、通信基站的后备电池组还是便携式储能电源两串结构都因为电压适中、成本可控而被大量采用。但很多人第一次做两串方案时会默认两颗电芯出厂参数一样串起来用就行了结果跑上几十个循环之后发现整组容量掉得比预期快得多充电时一颗先到保护点、另一颗还差一截放电时又反过来整组可用容量被最弱的那颗电芯死死卡住。这个现象的根源在于电芯一致性。即便是同一批次、同一产线的两颗电芯其实际容量、内阻、自放电率也会有细微差异。串联回路里电流是共同的但两颗电芯的端电压会随着SOC荷电状态的不同而逐渐拉开。容量偏小的那颗充电时先充满放电时先放空内阻偏大的那颗在大电流工况下压降更明显发热也更多。时间一长差异被不断放大形成所谓的木桶效应——整组的表现由最差的那颗决定。被动均衡也就是给电压高的那颗并一个电阻放电能缓解这个问题但它的本质是把多的能量烧掉效率低、发热大而且只在充电末期有效。对于储能和备用电源这种对循环寿命和能量利用率都有要求的场景主动均衡才是更合理的选择。主动均衡的核心思路是把电压高的那颗电芯的能量通过储能元件电感或电容搬运到电压低的那颗去而不是白白消耗掉。我这次做的方案就是用MP2642GR-Z这颗双向主动均衡芯片配合STM32L073RZ这颗低功耗MCU搭一套两串电池的主动均衡系统。选这两颗器件的理由很直接MP2642GR-Z 本身就是为两串电池主动均衡设计的专用芯片外围元件少、效率高STM32L073RZ 是STM32L0系列里的低功耗型号带LCD驱动、带丰富的定时器和ADC适合做电池管理这种需要长期在线、又要省电的场景。下面我把整个方案从器件理解、硬件设计、软件逻辑到实测踩坑完整拆一遍。提示本文涉及的所有参数和配置都是基于常见工程实践给出的参考值实际项目里一定要结合自己的电芯规格书和保护IC手册做调整不要直接照搬。2. MP2642GR-Z 这颗芯片到底怎么工作2.1 芯片定位与内部拓扑MP2642GR-Z 是一颗专门针对两串电池组设计的双向主动均衡器。它的工作方式不是简单的电阻放电而是通过一颗外部电感和一组内部开关管构成一个类似Buck-Boost的拓扑在上下两颗电芯之间双向搬运能量。具体来说芯片内部有四个功率开关管配合外部一颗电感形成两条能量通路一条是从上电芯到下电芯另一条是从下电芯到上电芯。芯片通过检测两颗电芯的电压差决定能量往哪个方向搬。当上电芯电压偏高时能量从上往下搬当下电芯偏高时反过来。整个过程是自动的不需要MCU干预方向判断MCU只需要负责使能、监控和异常处理。这种架构的好处很明显均衡电流可以做得比较大取决于外部电感的选择效率高能量是搬运而不是消耗而且因为开关频率较高电感可以做得比较小整体方案体积可控。2.2 关键引脚与外围元件MP2642GR-Z 的引脚不多但每一个都要接对。核心的几个VIN / VOUT分别接上电芯正极和下电芯正极也就是两串的中点芯片从这两点取电和判断电压。SW 引脚接外部电感的一端电感的另一端接中点。这是能量搬运的枢纽。EN 使能脚由MCU控制拉高启动均衡拉低关闭。电流检测相关引脚用来设定和监测均衡电流大小。外部元件里电感的选择是重中之重。电感值决定了均衡电流的纹波和峰值。电感太小电流纹波大EMI差芯片可能触发过流保护电感太大响应慢均衡效率下降。一般两串电池主动均衡的电感值在几微亨到十几微亨之间饱和电流要留足余量至少是设定均衡电流峰值的1.5倍以上。我实测下来选一颗饱和电流3A以上、直流电阻尽量小的屏蔽电感效果比较稳。另外输入输出电容也不能省。芯片在开关过程中会产生电流脉冲如果电容不够电压会被拉出纹波影响电压检测精度进而影响均衡判断。建议在上下两颗电芯的正负极之间各并一颗低ESR的陶瓷电容容值根据均衡电流大小选一般10μF到22μF起步。2.3 均衡电流的设定逻辑均衡电流不是越大越好。电流大均衡快但发热也大对电芯的冲击也大。对于储能和备用电源场景电芯容量通常不小均衡电流一般设定在几百毫安到一两安之间。设定方式通常是通过芯片的电流设定引脚外接电阻或者通过MCU给DAC/ PWM信号来动态调整。MP2642GR-Z 支持通过外部电阻设定一个基准电流MCU也可以在某些型号上通过PWM调节。我这次用的是外部电阻设定基准MCU只做使能和监控这样软件逻辑简单可靠性高。计算均衡电流的公式芯片手册里会给大致是I_balance V_ref / (R_set * K)其中 V_ref 是芯片内部基准R_set 是外部设定电阻K 是内部比例系数。实际选电阻时先确定想要的均衡电流再反推电阻值然后选最接近的标准阻值最后实测微调。注意均衡电流设定后一定要用电流探头或者串一个采样电阻实测确认不要只看公式。因为电感直流电阻、开关管导通电阻都会影响实际电流公式算出来的只是理论值。3. STM32L073RZ 在均衡系统里扮演什么角色3.1 为什么选低功耗MCU而不是普通MCU储能和备用电源系统有一个共同特点长期在线但大部分时间没事干。电池组可能几个月都处于浮充或者待机状态均衡动作只在电压差超过阈值时才触发。如果MCU一直全速运行功耗会白白吃掉电池的能量尤其是备用电源场景本来就是要靠电池撑时间的MCU自己耗电太多就本末倒置了。STM32L073RZ 属于STM32L0系列是ST的低功耗产品线。它的运行模式功耗可以做到很低停止模式Stop和待机模式Standby的功耗更是微安级别。而且它带LCD驱动如果系统需要本地显示电压、状态可以直接驱动段码屏不用额外加显示驱动芯片。它还带12位ADC、多个定时器、UART/I2C/SPI外设够用价格也适中。我选它的核心理由是在满足功能的前提下把静态功耗压到最低。均衡系统大部分时间在睡觉MCU的睡眠功耗直接决定了系统的待机损耗。L073在这方面的表现比普通F0/F1系列好太多。3.2 电压采集与均衡触发逻辑MCU要做的第一件事是采集两颗电芯的电压。两串电池的电压采集有个坑下电芯的电压是相对于系统地的上电芯的电压是相对于中点的不能直接用地做参考去测上电芯。常见做法有两种差分采集用运放或者专用差分放大器把上电芯的正极和中点之间的压差转换成对地的单端信号再送ADC。分压采集上电芯正极对地分压中点对地分压两者相减得到上电芯电压。这种方法简单但分压电阻会持续耗电而且精度受电阻匹配影响。我这次用的是差分采集方案因为备用电源对精度要求高分压方案的持续耗电和温漂都不太能接受。差分放大器选低功耗、低失调的型号输出直接进L073的ADC通道。采集到两颗电芯电压后MCU计算压差。压差超过设定阈值比如30mV且持续时间超过去抖时间比如10秒就拉高MP2642GR-Z的使能脚启动均衡。压差降到回差阈值比如10mV以下再关闭均衡。这个阈值回差去抖的逻辑是为了防止电压在阈值附近抖动导致均衡频繁启停那样既伤芯片又没效率。3.3 低功耗任务调度设计软件的主循环其实很简单但要把低功耗做好调度就得设计。我的做法是MCU大部分时间处于Stop模式用RTC定时唤醒比如每1秒唤醒一次。唤醒后开启ADC采集两颗电芯电压做滤波滑动平均或者中值滤波计算压差。根据压差和当前均衡状态决定是否使能均衡。如果需要均衡MCU可以继续睡让MP2642GR-Z自己工作MCU只定期醒来监控如果不需要直接回Stop模式。每隔一段时间比如每分钟通过UART或者I2C上报一次状态给上位机如果有的话。这样下来MCU的平均功耗可以压到几十微安甚至更低对电池组的影响可以忽略。提示Stop模式下ADC和部分外设会关闭唤醒后需要重新初始化。建议把初始化代码写成可重入的函数避免唤醒后外设状态不对。4. 硬件设计里最容易翻车的几个点4.1 电感选型不是随便找个电感就行前面提过电感重要这里展开说。MP2642GR-Z 的开关频率不低电感的工作频率就在这个频率上。如果选了一颗普通绕线电感它的自谐振频率可能不够高在高频下等效成一个电容能量搬运效率暴跌甚至芯片根本工作不起来。选电感要看三个参数电感值、饱和电流、直流电阻。电感值按芯片手册推荐范围选饱和电流要大于峰值电流留1.5倍余量直流电阻越小越好因为均衡电流直接流过它电阻大了发热严重效率也低。我踩过的坑第一次选了一颗电感值合适但饱和电流刚好卡在峰值电流上的电感结果一启动均衡电感就饱和电流飙升芯片触发保护均衡时断时续。换成饱和电流翻倍的电感后一切正常。所以饱和电流一定要留足余量这是血泪教训。4.2 电压采集的精度与滤波均衡判断的依据是电压差如果电压采集不准均衡逻辑就是错的。影响精度的因素有几个ADC参考电压L073的ADC可以用内部参考也可以用外部参考。内部参考精度一般如果对精度要求高建议用外部低漂移参考源。分压/差分电阻的温漂电阻的温漂会直接反映到采集结果上选低温漂电阻比如25ppm/℃会好很多。PCB布局采集走线要远离电感和开关节点否则开关噪声会耦合进来ADC读数跳动。我一般把采集走线走在底层用地平面隔开并且加RC滤波。软件上我用了滑动平均中值滤波的组合先连续采16次去掉最大最小各2个剩下的取平均。这样能有效抑制偶发噪声又不至于响应太慢。4.3 使能脚的电平与保护MP2642GR-Z 的使能脚由MCU的GPIO控制。这里要注意两点电平匹配L073的GPIO是3.3V逻辑MP2642GR-Z的使能脚阈值要看手册确认3.3V能可靠拉高。如果芯片使能脚是高压逻辑中间要加电平转换。上电时序MCU上电和芯片上电的先后顺序要理清。如果芯片先上电、MCU还没初始化使能脚处于浮空状态可能被干扰误触发。建议在使能脚上加一个下拉电阻确保MCU没起来之前芯片是关闭的。我遇到过使能脚浮空导致均衡意外启动的情况后来加了下拉电阻就再没出现过。这种小细节原理图评审时很容易被忽略但实际调试时很要命。5. 软件实现的完整链路与关键代码5.1 初始化与外设配置软件部分我用的是HAL库配置起来快。核心外设ADC1采集两路电压、RTC定时唤醒、UART2状态上报、一个GPIO控制使能脚。ADC配置要注意采样时间要够长因为差分放大器的输出阻抗可能不低采样时间短了采不准。我一般设成最长的采样周期比如239.5个ADC时钟周期。RTC配置成1秒周期唤醒唤醒中断里置一个标志主循环处理。// ADC采集单次 uint16_t adc_read(uint32_t channel) { ADC_ChannelConfTypeDef sConfig {0}; sConfig.Channel channel; sConfig.Rank ADC_RANK_CHANNEL_NUMBER; sConfig.SamplingTime ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(hadc, sConfig); HAL_ADC_Start(hadc); HAL_ADC_PollForConversion(hadc, 10); return HAL_ADC_GetValue(hadc); }5.2 电压计算与均衡决策采集到的ADC原始值要转换成电压。转换公式V_cell ADC_raw * V_ref / 4096 / Gain_diff其中V_ref是ADC参考电压Gain_diff是差分放大器的增益。两颗电芯都算出来之后求压差。均衡决策逻辑我用了一个状态机IDLE压差小于回差阈值均衡关闭。BALANCING压差大于启动阈值均衡开启。COOLDOWN均衡关闭后的一段冷却时间防止频繁启停。状态切换时除了看压差还要看去抖计数。只有压差持续超过阈值达到设定次数才真正切换状态。typedef enum { IDLE, BALANCING, COOLDOWN } bal_state_t; void balance_task(void) { static bal_state_t state IDLE; static uint16_t debounce 0; float v1 get_cell_voltage(CELL1); float v2 get_cell_voltage(CELL2); float diff fabsf(v1 - v2); switch (state) { case IDLE: if (diff START_THRESHOLD) { if (debounce DEBOUNCE_CNT) { HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_SET); state BALANCING; debounce 0; } } else { debounce 0; } break; case BALANCING: if (diff STOP_THRESHOLD) { if (debounce DEBOUNCE_CNT) { HAL_GPIO_WritePin(EN_GPIO_Port, EN_Pin, GPIO_PIN_RESET); state COOLDOWN; debounce 0; } } else { debounce 0; } break; case COOLDOWN: if (debounce COOLDOWN_CNT) { state IDLE; debounce 0; } break; } }5.3 低功耗模式的进出主循环里如果不需要做任何事就进Stop模式。进之前要关掉不用的外设时钟配置好唤醒源。L073进Stop模式后RTC继续跑唤醒后从Stop模式恢复继续执行。void enter_stop_mode(void) { HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); SystemClock_Config(); // 唤醒后重新配置时钟 HAL_ResumeTick(); }这里有个坑唤醒后系统时钟会切回HSI如果之前用的是HSE必须重新配置时钟否则串口波特率会不对。我第一次调试时忘了这步唤醒后串口输出全是乱码查了半天才发现是时钟问题。6. 实测数据与踩坑复盘6.1 均衡效果实测我用两颗标称容量5000mAh、初始压差约80mV的电芯做测试。设定均衡电流500mA启动阈值30mV回差10mV。时间上电芯电压下电芯电压压差状态0min3.92V3.84V80mV启动均衡30min3.89V3.87V20mV继续均衡45min3.88V3.88V0mV关闭均衡120min3.87V3.87V0mV保持从80mV压差到基本一致用了大约45分钟。这个速度对于储能场景完全够用因为均衡是长期慢过程不追求几分钟搞定。6.2 踩过的坑均衡时电压采集跳变调试初期遇到一个怪现象均衡一启动ADC采集的电压就跳变压差读数忽大忽小导致均衡频繁启停。用示波器看发现是电感的开关噪声耦合到了采集走线上。解决办法有两个一是硬件上把采集走线远离电感加RC滤波二是软件上在均衡启动后稍微延迟再采集避开开关瞬间。我两个都做了问题解决。这个坑很典型开关电源和模拟采集共存时布局和滤波一定要提前考虑不要等出了问题再补救。6.3 踩过的坑Stop模式唤醒后外设异常前面提过时钟问题其实还有ADC。Stop模式下ADC是关闭的唤醒后如果直接调用采集函数ADC可能还没稳定。我的做法是唤醒后先重新初始化ADC加一个小延时再开始采集。另外Stop模式下GPIO状态会保持使能脚如果之前是拉高的唤醒后还是拉高这个要注意别让均衡在MCU不知情的情况下一直开着。6.4 踩过的坑电感发热一开始选的电感直流电阻偏大均衡电流500mA时电感发热明显手摸上去烫。虽然没到损坏的程度但长期运行肯定不行。换成低直流电阻的屏蔽电感后温度降下来了。电感发热是效率的直接体现发热大说明能量被浪费了选型时一定要看直流电阻这个参数。7. 几个值得提前想清楚的设计取舍7.1 均衡电流取大还是取小均衡电流大均衡快但发热大、对电芯冲击大、电感体积大。均衡电流小发热小、元件好选但均衡慢。对于储能和备用电源我倾向于取中等偏小比如0.1C到0.2C的电流。因为这类场景对均衡速度不敏感更看重长期可靠性和低损耗。5000mAh的电芯500mA到1A的均衡电流是比较舒服的区间。7.2 MCU是常开还是间歇工作常开的话软件简单响应快但功耗高。间歇工作功耗低但响应慢软件复杂。我选间歇工作因为备用电源场景对响应速度要求不高压差是慢变量1秒采集一次完全够。如果你的场景要求快速响应那就得让MCU常开或者用更快的唤醒周期。7.3 要不要做状态上报如果系统是独立运行的没有上位机那状态上报可以省掉进一步降功耗。如果系统需要远程监控那就得加上报功能可以用UART、I2C或者无线模块。上报频率不用高每分钟一次足够因为电池状态变化很慢。8. 写在最后的一点个人体会这套方案我前后调了大概两周大部分时间花在硬件布局和低功耗调试上软件逻辑本身不复杂。MP2642GR-Z 这颗芯片的集成度确实高把双向均衡的功率级都做进去了外围只需要电感电容省了很多事。STM32L073RZ 的低功耗表现也符合预期Stop模式下整机静态电流压到了几十微安。如果让我给后来者一句建议那就是先把电压采集做准再谈均衡。均衡逻辑再漂亮采集不准都是白搭。采集准了阈值、回差、去抖这些参数才有意义。另外电感选型和PCB布局是硬件里最值得花时间的地方这两块做好了调试会顺很多。后续如果要做更多串的均衡MP2642GR-Z 这种两串专用芯片就不够用了得换成支持多串的均衡方案或者用多个两串模块级联。那是另一个话题等有机会再拆。