做电池管理系统(BMS)相关开发的朋友,十有八九都要跟CC-CV充电策略打交道。锂离子电池的恒流恒压充电(CC-CV)是当前最主流的充电方式,没有之一——先用恒定电流快速把电量充到七八成,再切换到恒定电压把最后一截慢悠悠补进去,速度和安全性两头兼顾。这次我整理了一个用Simulink搭建的锂离子电池恒流恒压充电仿真模型,从电池等效电路、PI控制器到状态切换逻辑,从模型选型到参数整定一步步拆开讲,顺便把调模型时踩过的坑一并列出来。这个内容适合正在做BMS仿真、充电策略设计的工程师,也适合刚接触Simulink、想找一个能跑通的完整示例来练手的朋友。
1. 先搞懂CC-CV充电策略为什么是行业标准
1.1 两阶段充电的接力逻辑
锂离子电池不能像铅酸电池那样随意大电流硬灌。它的充电曲线被严格划分成两个阶段:先是恒流(CC,Constant Current)阶段,控制器维持一个固定电流往电池里灌,通常取0.5C到1C倍率,例如一块2Ah的电池用1A到2A充电;此时电池端电压随着电量累积逐渐爬升,当升到厂家规定的截止电压(常见4.2V或4.35V)时,立即切入第二阶段——恒压(CV,Constant Voltage)阶段,电压死死压在4.2V上不动,电流则随荷电状态(SOC)升高自然衰减,直到电流降到截止电流(一般是0.05C到0.1C,即100mA到200mA)就认为充电完成,彻底切断。
为什么要这样设计?因为锂离子电池在恒流阶段如果继续用大电流冲到电压平台之上,正极材料的结构会被破坏,负极表面容易析出金属锂,导致容量衰减甚至内部短路。而只恒流不恒压又充不满——电池极化电压会让端电压虚高,实际_SOC还不到100%。CC阶段冲得快,CV阶段补得满,两个阶段接力,就是锂离子电池充电策略最重要的底层逻辑。仿真模型里要做的事,就是把这条接力赛跑完整的复现出来。
1.2 截止电压和截止电流为什么是硬指标
截止电压和截止电流这两组数字,是CC-CV策略里最不能妥协的参数。截止电压本质上是厂家根据正极材料、电解液体系和负极容量算出来的安全上限,超过这个值,电解液会在高电位下氧化分解,SEI膜被破坏,产气、鼓包都跟着来。截止电流则是从恒压阶段"毕业"的门槛,理论上在CV阶段电流要降到无穷小才能把电池完全充满,但实际没人愿意等那么久,所以用0.05C作为"充得差不多了"的标志,此时SOC通常能到99%以上,再往下充的容量增量极小,却会显著拉长充电时间。
我在模型里给截止电流留了一个可调的常量参数,就是方便对比不同截止电流下充电结束时间和SOC的差异。你会看到截止电流从0.1C降到0.05C时,充电时间可能要延长20%到30%,但SOC只多充进去不到2%,这就是工程实践里的"边际收益递减",做充电策略的人必须心里有数。
1.3 切换过程的本质:从电流闭环切到电压闭环
很多第一次搭CC-CV模型的人会卡在切换逻辑上:CC和CV都盯着同一块电池,到底谁说了算?理解这个问题有个关键视角——切换的本质不是"电压到了就改电流",而是控制环路的切换。CC阶段用的是电流闭环,电流给定值就是恒流目标值,电压是跟随量;CV阶段用的是电压闭环,电压给定值就是截止电压,电流变成跟随量。两个环路共用一个功率回路,任何时刻只允许一个环在起作用。
在纯Simulink环境里做这种切换,最直观的做法是取两路调节器输出中"更安全"的那个。按锂离子电池的充电逻辑,CC阶段要限制电流,CV阶段要限制电压,所以可以用开关逻辑或取最小值模块来切换。如果用了Stateflow,就更讲究了——状态图里画两个状态,CC状态下电流环闭合电压环断开,当端电压大于等于截止电压瞬间触发跳转,CV状态下电压环闭合电流环断开,当电流小于等于截止电流时跳到终止。这种状态机的表达方式会清楚得多,后面调试的时候逻辑也更顺。
2. 锂离子电池仿真模型的选型与搭建思路
2.1 一阶RC模型 vs 二阶RC模型,我为什么推荐一阶起步
搭建CC-CV仿真,首先要解决"电池本体怎么表示"的问题。锂离子电池内部电化学过程极其复杂,但做系统级仿真的人通常不需要把正负极材料、电解液浓度分布都搬进Simulink,用等效电路模型(ECM)就足够了。最常见的是一阶RC模型:电压源OCV(SOC)串联一个欧姆内阻R0,再并联一个极化电阻Rp和极化电容Cp构成的RC网络。一阶RC端电压方程可以写成:
Vt = OCV(SOC) - I × R0 - Up
其中Up是极化电压,一阶RC下满足: Up + Rp×Cp×dUp/dt = I×Rp
这个模型描述了一个关键现象:电流突变的时候,欧姆内阻引起电压瞬时跳变,RC网络则让你看到一个"慢慢爬坡"的极化过程。用生活化类比,就是水管系统里突然开大阀门,水压先是瞬间掉一小截,然后随着管道壁的弹性慢慢稳住。一阶RC模型捕捉到的就是这个"瞬态跳变+缓变收敛"的双重特性,参数也少,只有R0、Rp、Cp三个,对比数据拟合时不容易搞出过拟合。
二阶RC模型再多一组RC网络,能更精细地刻画浓差极化和电化学极化两个不同时间尺度的过程,精度是高,但参数辨识的工作量翻倍,而且对CC-CV这种毫秒级到秒级响应的应用来说,一阶RC的误差在可接受范围内。我的建议是:先搭一阶RC把整个控制链路跑通,如果后续做高精度SOC估计或者跟实验数据对标,再升级二阶。
2.2 OCV-SOC特性曲线的获取和处理
等效电路里那个电压源OCV(SOC),是整个模型最不能马虎的部分。它描述的是一条从SOC=0到SOC=100%的开路电压曲线,锂离子电池的典型特征是在中间平台区(SOC 20%~80%)电压变化很平缓,两头陡峭。建模时有三种获取途径:
- 直接用实验数据:把电池小电流充放,每变化5% SOC静置一段时间测开路电压,然后插值查表。
- 用Simulink自带的Battery模块:里面预置了几套典型数据,适合快速验证。
- 用多项式拟合文献数据:通过仿真数据或经验参数拟合出OCV与SOC的关系。
我实际建模用的是查表法,Simulink里放一个Lookup Table模块,SOC作为输入,输出OCV。查表法的好处是忠实于实验数据,不需要硬套数学公式,而且如果你想模拟"老化了以后的电池",直接替换一张衰减后的OCV曲线就行。需要注意查表的时候要在Simulink设置里勾选“使用端点插值”,防止SOC跑到0以下或100以上时产生非法外推值。
2.3 自带Battery模块和自建ECM子系统的取舍
Simulink/Simscape里自带锂离子电池模块,参数填一下就能跑,非常省事。但我个人更推荐自建一阶RC子系统,理由有三点。第一是透明性:自建模型里SOC、极化电压Up、欧姆压降Uo全部拉出来单独走线,你可以用Scope同时观察好几路信号,训练自己理解"电流变化时每一部分压降怎么响应",自带模块则是一个黑盒,想看看内部状态反而麻烦。第二是可控性:你可以随时往模型里加入电容老化、温度影响、SOC-内阻耦合等扩展因素,自带模块在这方面扩展起来比较别扭。第三是教育价值:如果你要拿这段模型去跟同事讲解或培训,一笔一笔算出来的端电压比一个封装块更有说服力。
当然,如果是做顶层系统方案比选、不想纠结电池内部细节,直接用自带模块完全没问题。我的习惯是先用自建模型完成全部调试,跑通了以后再看是否需要替换成厂商标定过的模块,这样每个环节的物理意义都清清楚楚。
3. Simulink模型搭建实操:从零到能跑
3.1 顶层架构到底要放哪些部分
一个完整的CC-CV充电仿真模型,顶层至少要有四块内容:电池模型、控制策略、被控对象接口和观测模块。电池模型就是上面说的一阶RC子系统,输入是充电电流(正方向定义为流入电池),输出是端电压Vt、SOC、极化电压Up。控制策略这块要生成两个关键信号:电流环的输出和电压环的输出,再加上状态切换逻辑,最终合成一个电流指令送到电池模型。观测模块就是Scope、Data Inspector,用来记录Vt、I、SOC、Up随时间的变化曲线。
实际接线时需要特别注意信号的正负号约定。我建议统一规定:流入电池的电流为正,充电时电流为正,放电时电流为负。整个模型里只用一套符号规则,否则很容易出现"明明在充电,SOC却往下掉"的诡异现象。我在模型里特意加了一个Gain = -1的模块放在电池模型前面,这样控制端输出正值电流表示充电,进入电池模型后再反转成放电方向,直观且一致性好。
3.2 用逻辑判断还是用Stateflow实现CC-CV切换
两种方案我都用模型实践过,各有使用场景。方案一,纯Simulink逻辑判断:用电压比较器判断Vt是否到达截止电压,再用一个Switch模块选择电流环输出还是电压环输出。这种方法搭建快,适合快速验证,但有个隐患——切换瞬间如果两个闭环的输出没有处理平顺,电流指令会产生一个阶跃,仿真步长不够小的话很容易出现数值振荡。
方案二,Stateflow状态机:我强烈推荐在正式模型里用这种结构。它把控制策略画成三个状态:CC_CHARGE、CV_CHARGE、END。CC_CHARGE里激活电流环,当Vt >= V_max时跳到CV_CHARGE,同时把电流环输出冻结成当前值作为初值;CV_CHARGE里激活电压环,当电流 <= I_cutoff时跳到END并令电流指令为0。Stateflow的好处是状态跳转逻辑一目了然,而且可以利用状态内动作和迁移动作精确控制切换时刻的平滑过渡,避免数值冲击。
切换时还有一个容易忽略的细节:电流环PI控制器和电压环PI控制器各有一套积分状态,切换时如果不做处理,积分器的初值可能让输出产生大幅跳变。我的做法是在CV切换进入时,把电流环PI的输出清零,同时给电压环PI的积分器赋一个合理初值(等于切换时刻的电流指令),这样切换前后电流指令能够连续。这个细节不处理,仿真图上就会出现一个很扎眼的小尖峰。
3.3 PI控制器参数整定的土办法
CC-CV模型里的PI参数不能靠猜。我用的方法是分环整定:先只保留电流环,给定一个恒定电流阶跃,手动调Kp和Ki。Kp先给一个较小的值,比如0.1,观察电流响应超调量,然后逐渐加大到超调不超过5%;Ki则负责消除稳态误差,我在仿真里让电流阶跃持续2秒,看稳态时电流是否精确回到设定值,不够就加Ki。
电压环的整定思路一样,但要注意两个环的响应速度必须拉开差距。正常逻辑应该是电流环快、电压环慢,这样在CV阶段电压才能平稳地稳住,不会一会儿超调一会儿又跌回来。我的经验参数是:电流环Kp=0.2,Ki=0.5;电压环Kp=0.05,Ki=0.1,这个数值在2Ah电池模型上实测下来超调量很小,切换也比较平滑。但给到不同容量、不同内阻的电池时,必须配合仿真结果重新微调,没有一刀切的万能参数。整定过程中一定要用Scope盯住两个PI的输出变化,调参慢一点没关系,稳字当头。
4. 关键参数设置与调试心得
4.1 求解器配置直接影响切换瞬间的收敛性
同样的模型,求解器配置不同,仿真结果可能差一个量级。CC-CV充电过程里,状态切换点处有一个硬事件——控制策略从恒流改恒压,电流指令的斜率发生突变。如果使用定步长求解器,步长太大,切换点可能落在几步之后,引起电压过冲或电流振荡;步长太小,仿真时间又被拖长。
我的建议是用变步长求解器,类型选ode15s或ode23t。很多人不理解为什么不用默认的ode45,原因很简单:电池模型里的RC网络时间常数、PI控制器的动态、切换逻辑的离散状态混在一起,系统具备刚性特征,ode45这种非刚性的Runge-Kutta法会为了维持精度把步长压到极小,跑起来又慢又容易报错。ode15s是数值差分公式法,对刚性问题更稳,仿真速度也明显更快。另外一个容易被忽略的参数是“最大步长”,我习惯把它约束在1e-3秒以内,这样即使变步长算法在平坦区想猛冲,也能保证切状态前后不会跨步太大。
4.2 初始SOC和内阻的设定影响启动瞬态
模型开始时电池尚未充电,SOC初始值由常量模块决定。如果你的SOC设成0,电池OCV处于曲线上最低点,此时突然投入恒定电流,端电压会先跳变一个欧姆压降的量。这个跳变是正常的,但如果你把初始SOC设成50%而曲线标定又有偏差,启动阶段的电压表现就不够真实。我在实践中的办法是初始SOC设为5%,贴近实际电池出厂时的剩余电量状态,同时检查OCV表在SOC低端的查表数据是否平滑,因为低SOC段如果相邻点斜率反差大,启动瞬间的电压变化率会非常怪。
内阻参数的影响更直接。电池在低温或老化以后内阻变大,同样的充电电流下,欧姆压降I×R0明显增大,端电压会更早触达截止电压,CC阶段提前结束,总体进入CV阶段的时间提前、充电容量反而减少。你在调试模型时可以故意把R0从0.05Ω提高到0.2Ω,观察CC阶段时长急剧缩短,这个现象就是"老电池充电变慢"这件事的仿真根源。
4.3 为什么一定要加饱和限幅和变化率限制
控制策略输出的电流指令,必须经过饱和模块限制到电池允许的最大充电电流范围内。假设恒流目标设1C,而电压环在切换瞬间由于误差较大输出一个30A的指令,如果没有饱和模块,电池模型的电流输入端瞬间受到巨大冲击,仿真结果毫无意义。在Simulink里放一个Saturation模块,下限设0,上限设最大充电电流,简单有效。
另外一个更加"工程向"的细节是电流变化率限制。真实充电设备里,功率电子器件不能瞬间从一个电流值跳到另一个电流值,需要一定的电流爬升率。模型中加一个Rate Limiter模块,把变化率限制在比如0.5A/s,这样仿真出来的电流曲线更接近真实充电桩的表现。如果你直接做阶跃电流,得到的是理想化的快速响应曲线,这在纯算法验证阶段没问题,但想跟实测数据对照,加上这一层限制会让结果更有参考价值。
5. 仿真结果分析与曲线判读
5.1 一张标准充电曲线应该长什么样
模型跑通以后,把Scope里的Vt、I、SOC三条曲线拉出来,正确的结果是这样:CC阶段开始,电流恒定在设定值,端电压从初始OCV加上欧姆压降处起步,然后由于极化累积缓慢爬升,同时SOC线性增长;当Vt到达截止电压时(比如4.2V),电流指令开始快速下降,进入CV阶段,端电压保持在4.2V水平线上微微波动,电流按指数规律衰减,SOC增速放缓;当电流衰减到0.05C以下,充电终止,电流归零,端电压瞬间回落到OCV水平,这就是充电结束后的"电压回缩"现象。很多同学第一次看到充电完成时电压突然掉下来会以为模型出错了,其实这是真实电池特性——电流消失后欧姆压降和极化压降同时消失,端电压自然回到无负载的开路电压。
5.2 通过对比不同倍率来验证模型行为
验证模型对不对,有一个好办法:跑三组不同充电倍率的仿真。分别用0.5C、1C、2C做恒流阶段的电流值,记录CC阶段时长、总充电时长、CV阶段电流衰减曲线。预期的结果是:倍率越大,CC阶段越短,因为极化电压更大,端电压更早到达4.2V;相应的CV阶段拖得更长,因为高倍率下末端还有大量的极化电荷需要"慢慢磨"。如果说没有这个趋势,比如2C充电反而比0.5C更早结束整个流程,那基本可以判断极化电阻参数设置有问题,或者CV阶段切换逻辑过早介入了。
我实际跑出来的数据举个例子:2Ah电池,0.5C充电全程大约需要3.2小时,其中CV阶段约40分钟;1C充电全程约1.8小时,CV阶段约35分钟;2C充电约1小时,CV阶段反而占到45分钟。这个规律跟文献里对锂离子电池充电行为的描述是吻合的。你在自己模型里看到接近的比例关系,说明模型的核心行为是可信的。
5.3 仿真与实测对标时最容易忽视的温差因素
如果想拿仿真结果跟真实电池充电曲线对标,一定要把温度因素剥离出来单独处理。锂离子电池内阻和极化参数随温度变化极快,同一块电池在25℃和5℃下的充电曲线差异巨大。仿真模型中如果所有参数都是常温定值,它在低温场景下必然和实测严重偏离。
我在模型中预留了一个温度输入接口,把R0、Rp、Cp都做成SOC和温度的三维查表,但这是后来迭代的事情。第一版建模时用常温25℃参数跑通全流程,验证控制逻辑正确后再扩展温度维度。如果一上来就把温度搞进去,参数太多导致你根本分不清某个波形异常到底是控制参数问题、电池模型问题还是温度参数的问题。
6. 常见问题与排查技巧实录
6.1 CC阶段电流没有稳住是什么原因
现象是恒流指令设了1A,但Scope里显示的电流一直慢慢飘,甚至振荡。排查顺序如下:先确认PI控制器是否真的在闭环工作——如果电流反馈信号接错或正负号弄反,环路的输出会往错误方向调整。再检查饱和模块要不要改成合理上下限。还有一个经典问题:PI控制器输出指令进入了电池模型,但电池模型的SOC不能用一分钟更新一次,导致端电压出来以后再反馈到输入端时,整个环路出现时滞,表现出来就是电流低频振荡。解决方法是把电池模型和控制器放同一个仿真步长下,不要用离散采样模块给反馈信号做"降采样"。
6.2 切换瞬间电压出现尖峰怎么办
CC阶段末段电压已经隐约碰到4.2V,切换后Vt却冲到了4.3V以上才回落到4.2V,这是典型的切换冲击问题。原因大概率是切换瞬间两个PI控制器输出不连续,电流指令产生了台阶。按第3章说的方法处理:进入CV状态时给电压环积分器赋初值,同时让电流环输出跟着当前电流连续过渡。如果还不行,把最大步长调得更小,例如5e-4秒,看看尖峰是否明显收敛,通过这个手段可以区分"控制逻辑问题"和"数值精度问题"。
6.3 SOC跑到99%就显示充电完成,但容量感觉不对
这大概率不是控制逻辑的问题,而是OCV-SOC曲线标定偏差。查表法里,如果你SOC=100%对应的OCV设置偏低,那么充电后期OCV增速已经非常平缓,CV阶段电流衰减到截止电流时,SOC内插结果达不到100%,显示就停在99%左右。这不是大问题,绝大多数实际BMS策略本来就不会把SOC卡死在100%,通常以电流截止作为结束条件。但如果你的场景里SOC到达100%是一个里程碑,那就需要重新标定OCV表末段的数据,保证SOC=100%处的OCV与截止电压匹配。
6.4 常见问题速查表
| 现象 | 可能原因 | 排查建议 |
|---|---|---|
| CC阶段电流无法稳定 | 反馈正负号错误、PI参数增益不合适 | 检查电流反馈极性,从小到大调Kp |
| CV阶段电压超调 | 切换时PI积分初值未处理 | 给电压环积分赋切换时刻电流初值 |
| 仿真速度极慢 | 使用了非刚性求解器 | 换成ode15s或ode23t |
| SOC曲线在充电完成后回落 | 正常现象,端电压回缩所致 | 不用处理,对比OCV曲线判断即可 |
| 切换边界频繁抖动 | 最大步长过大导致切换事件延迟 | 将最大步长限制在1e-3秒以下 |
| 找不到状态切换模块 | 使用了Simulink而不是状态机工具 | 添加Stateflow或改用逻辑切换方案 |
7. 最后的一点实际操作体会
模型本身并不复杂,真正体现功力的地方在于两点:一是把电池模型的每个参数变化都跟物理过程联系起来,二是把数值求解的细节处理到位,二者缺一不可。我最初搭这套CC-CV模型的时候,最大的收获不是学会了放几个Simulink模块,而是搞清楚了一个道理——仿真模型的意义不在于"看起来像",而在于"关键行为机理一致"。当你把内阻变大导致CC阶段缩短、截止电流调高导致充电提前结束这类规律都在Simulink里复现出来的时候,这个模型才真正属于你的工具箱。
如果后续想继续扩展,我建议优先做两件事。一是加入温度维度,把R0和极化参数都做成随温度变化的表达式,这样就能直接模拟冬天低温充电变慢的现象,也能拿来分析低温析锂的风险窗口。二是把单节电池的CC-CV模型扩展成多节串联电池组,这时因为单体一致性差异,某些电芯会先到达截止电压,整个充电策略就会从"整包恒压"变成"先到先限"的复杂逻辑,这对BMS策略设计来说是很值得深挖的方向。这次就先写到这,希望这个模型搭建的完整思路对你的项目有直接帮助。