锂离子电池在现代生活里几乎无处不在,手机、笔记本、电动车、储能电站都在用它。而充电又是电池使用中最关键的环节,充不好轻则容量衰减,重则热失控。这次要讲的这个Simulink恒流恒压(CC-CV)充电仿真模型,就是把锂电池充电过程在电脑里完整复现出来的工具。通过它,你可以直观看到电池端电压、充电电流、SOC在几分钟内的演化规律,理解为什么商用充电器都采用“先恒流、后恒压”的策略,也可以在这个模型基础上做自己的控制算法验证。这篇文章适合正在做电池管理系统(BMS)开发、电源设计、储能相关课题的工程师和研究生,也适合刚接触Simulink但想快速上手电池建模的初学者。我会把模型结构、控制原理、参数整定、仿真分析到踩坑经验全部掰开来讲。
1. 项目整体设计与建模思路拆解
1.1 为什么充电控制需要CC-CV策略
先回答一个最基本的问题:为什么不用固定电压直接充?锂电池对充电过程极其敏感,如果直接用高于电池电压的电源硬充,电流会不受控地飙升,瞬间超过电池允许的最大充电倍率,轻则保护板动作,重则电池内部析锂、产气、甚至起火。反过来,如果用很小的电流一直充,充电时间会拉长到无法接受的程度,丧失实用性。
CC-CV策略本质上是一种“两头兼顾”的妥协:先以恒定电流快速充电,等电池电压上升到截止电压(比如单体4.2V),再切换为恒压充电,此时电流自然衰减,直到降到截止电流(通常是0.05C~0.1C)就停止。这个策略既保证了充电速度,又控制了最终电压精度,是目前几乎所有锂电池充电方案的基础框架。
1.2 选择Simulink做仿真的原因
可能有人会问,这个仿真用Python写个数值积分也能做,为什么非得用Simulink?我个人的体会是:Simulink在“电机/电力电子/控制”这条链路上的模块化优势太明显了。CC-CV充电不是单纯的电池方程求解,它涉及到电力电子开关(PWM)、PI控制器、采样保持、逻辑切换,这些环节在Simulink里都有现成模块,而且可以实时调参、可视化观察波形。
另一个关键点在于“多物理域耦合”。实际充电系统里,电池是电化学对象,MOSFET开关是电力电子对象,控制器是数字逻辑对象,三者在传统编程里需要自己处理接口,但在Simulink里只需要拖拽连线。同时,Simulink的 Simscape Electrical 工具箱提供了电池、MOSFET、电感电容等物理模型,不需要自己推导一堆微分方程再手写求解器,建模门槛低了不少。
1.3 模型整体架构分区规划
拿到这个任务,不要急着往画布里堆模块,先想清楚整个模型需要哪几个功能区。我建议把模型分成四个核心子系统和若干辅助模块:
- 电池子系统:模拟锂离子电池的动态特性,包括开路电压(OCV)、欧姆内阻、极化效应、SOC积分。
- 功率变换子系统:用受控电压源或DC-DC变换拓扑,模拟充电器对电池的功率输入,核心是MOSFET开关与PWM占空比控制。
- 控制子系统:实现CC和CV模式的检测与切换、PI调节器、PWM发波。
- 保护与逻辑子系统:负责过压、过流保护,充电终止判断。
按照这个分区设计,模型的逻辑就非常清晰了:控制子系统采集电池的电流电压信号,经过PI运算输出PWM占空比,功率子系统根据占空比对电池进行充电,电池子系统把新的端电压和SOC反馈给控制子系统,形成闭环。
2. Simulink模型核心模块拆解与参数计算
2.1 锂离子电池等效电路模型搭建
仿真中电池模型的精度直接决定结果的可靠性。最常用的是二阶RC等效电路模型,比单纯Rint模型多考虑了一个极化效应:
- 理想电压源 U_oc 表示开路电压,它不是一个定值,而是随SOC变化的函数,需要通过查阅电池数据手册或做OCV-SOC标定实验得到曲线。仿真时用一维查表模块(Lookup Table)拟合这条曲线。
- 欧姆内阻 R0 模拟电解液和极耳的接触电阻,通常取值在几毫欧到几十毫欧之间;R1C1网络表示电化学极化,时间常数在秒级;R2C2网络表示浓度差极化,时间常数在数十秒级。
参数怎么定?可以做一个简化处理:R0取电池规格书中25℃条件下的内阻值;R1C1、R2C2的数值如果手头没有实验数据,可以参考同类电芯的常用经验值,我这边的初始设定是 R1=R2=R0,C1对应时间常数1s,C2对应时间常数10s。这样虽然不算精准,但作为控制策略验证已经完全够用。
端电压的计算式就是:
U_t = U_oc(SOC) - U_R0 - U_RC1 - U_RC2
其中 U_RC1、U_RC2 分别是两个RC网络的极化电压,它们的微分方程可以在Simulink里用积分器搭出来。
2.2 OCV-SOC标定与查表实现
OCV-SOC曲线是电池模型的灵魂。如果仿真里的OCV曲线严重失真,那么恒压阶段的电压切换点、SOC估算都会跟着出错。
做标定的常规流程是:满充后静置足够时间,然后以小倍率(0.05C)间隔放电,每放出一部分电量就静置一段时间,记录稳定的开路电压。把“磷酸铁锂”“三元锂”等不同材料的曲线对比一下,会发现三元的OCV曲线比较陡峭,而铁锂在中间区间有一段很平的区域,这直接影响了恒压切换时SOC估算的精度。
如果手上没有真实电池数据,可以先用一个经验公式或从文献里找近似曲线。例如常见三元锂电池的OCV-SOC曲线可以用式(1)近似,但更推荐的做法是:找一组实测数据点,用Lookup Table模块直接插值,这样曲线形状更接近真实电芯。
2.3 功率变换级与控制环建模
这一块是整个模型里最容易出问题的地方,因为它涉及到开关器件和PWM信号。最简单的方案是使用Buck拓扑:输入直流母线电压,通过MOSFET和二极管输出可调电压,配合电感电容滤波。在Simulink中,可以用Simscape元件搭建,也可以简化成受控电压源。
个人建议:如果你的目标偏向控制策略验证而非电力电子细节分析,可以牺牲掉部分电力电子精度,用受控电压源加一阶惯性环节模拟功率变换的响应,这样仿真速度更快,也不容易遇到Simscape微分代数环收敛困难的问题。如果目标是硬件在环或损耗分析,再换成真正的Buck电路。
电流反馈用Current Sensor模块,电压反馈直接在电池端并联一个Voltage Sensor。PI调节器的输出经过饱和限幅后,作为PWM发生器的调制波输入,与高频载波比较生成驱动脉冲。载波频率一般取10kHz~20kHz,兼顾开关损耗和控制带宽。
3. 仿真参数设置与控制策略深度解析
3.1 关键参数清单与初始化
我把整模型需要的初始参数整理成一张表,方便直接抄作业:
| 参数名称 | 推荐值 | 说明 |
|---|---|---|
| 电池额定容量 | 2Ah | 典型小容量软包电芯,便于缩短仿真时间 |
| SOC初值 | 20% | 模拟低电量开始充电,观察完整流程 |
| 满电截止电压 | 4.2V | 三元锂单体典型值 |
| 额定最大充电电流 | 1A(即0.5C) | 充电倍率过高会影响寿命且不安全 |
| 截止充电电流 | 0.1A(即0.05C) | 低于该值判定充电完成 |
| 恒流阶段PI参数 | Kp=5,Ki=50 | 以电流误差为输入,输出占空比 |
| 恒压阶段PI参数 | Kp=1,Ki=5 | 以电压误差为输入,输出占空比 |
| PWM载波频率 | 10kHz | 低于开关管最大频率,高于控制带宽 |
| 母线电压 | 5V | 高于电池满电电压,留出Buck降压裕量 |
需要注意,PI输出限幅必须设置在合理的占空比范围,比如0.05~0.95,否则仿真开始瞬间超过实际Buck的调节能力,系统会长时间饱和。
3.2 恒流阶段控制逻辑与PI参数整定
恒流阶段的目标是让充电电流紧贴设定值。这个阶段电池端电压缓慢升高,但远未达到截止电压。控制环的结构是电流外环加PWM内环:
电流参考值设为1A,反馈值为电池充电电流实测值,两者相减得到误差,进入PI调节器。PI输出作为PWM占空比。电池端电压上升会导致充电电流减小,PI检测到误差后自动调大占空比,从而维持电流恒定。
关于PI参数整定,我常用试凑法:先设Ki=0,逐渐增加Kp直到电流出现等幅振荡,此时的Kp记为临界增益;然后取Kp为临界值的60%左右;再缓慢增大Ki消除静态误差。这样整定出来的参数一般不会太差,后续再根据响应波形微调。
实际操作中有个容易忽略的点:电流反馈信号需要加滤波。PWM开关频率10kHz,电流波形不可避免会有纹波,如果不滤波直接进PI,控制器会输出一个带高频振荡的占空比,导致电流波动更严重。我的做法是加一个100Hz~1kHz截止频率的一阶低通滤波器,视控制带宽需要而定。
3.3 恒压阶段控制逻辑与电压精度
当电池端电压达到4.2V时,控制目标从“保持电流”切换到“保持电压”。此时电流给定无效,变为电压给定4.2V,反馈为电池端电压。如果电压实测稍低,PI会自动增大充电电流;一旦电压上升接近4.2V,电流被逐步压小。在这个阶段,电流不是控制目标,而是自然衰减的输出结果。
恒压阶段的PI参数要保守一些,否则会在切换点引入电压超调。我一般把Kp设为恒流阶段的1/5~1/3,Ki也相应调小。为什么?因为电池极化电压在恒压阶段是缓慢变化的,如果积分作用太强,PI输出占空比会大幅摆动,造成电流反复充放,长期下来等效的“微循环”非常伤电池。
3.4 模式切换判定与防抖处理
CC到CV的切换是模型里最考验细节的地方。最简单的做法是:用端电压是否大于等于截止电压作为切换条件,加一个滞环比较器。滞环宽度设50mV,比如电压达到4.2V才切到CV,回落到4.15V才切回CC。这么做的好处是防止在临界点附近控制器频繁切换模式,造成电流和电压波形震荡。
另一个容易被忽略的点是:切换时PI控制器的历史状态(积分项)必须正确处理。如果CC切CV瞬间,把两个PI的积分值都清零,占空比输出会跳变,相当于给电池来一个阶跃扰动;如果不清零,旧的积分值会继续影响新PI输出,可能导致电压超调。我的经验是:切换瞬间把积分器初值设为当前PI输出的等效值,实现“无扰切换”。
4. 实操过程与仿真结果波形解读
4.1 搭建模型的完整顺序建议
既然要把模型跑出来,我就按我平时搭模型的节奏,一步步说明。
第一步,新建一个Simulink模型,把仿真类型设置为定步长(Fixed-step),步长取1e-6秒,求解器选ode4(Runge-Kutta)。如果你用的是PWM载波10kHz,定步长必须小于载波周期的1/50,即2e-6秒,否则PWM波形会出现明显的抖动甚至无法正确表示占空比。
第二步,从Simscape Electrical库中拖入电池模块(Battery (Table-Based)),或者按2.1小节的方案自己搭等效电路模型。我实际跑下来,自己搭的等效电路模型更灵活,因为可以随时观察内部各极化电压的状态,这对调试很有帮助。
第三步,搭电流采样和电压采样模块,并把SOC积分器初始化。SOC可以用安时积分,表达式是:
SOC = SOC_0 - (1 / Q_capacity) * ∫ I_charge dt
注意充电电流为正,减去的电量是负值,SOC会从初值上升。
第四步,搭控制子系统。用两个PI控制器(一个用于CC,一个用于CV),通过饱和限幅和切换逻辑输出最终的占空比命令。模式切换逻辑用Stateflow模块最方便,但也可以用Subsystem+比较器实现,避免引入新工具箱。
4.2 完整仿真波形解读:从CC到CV到截止
仿真时间设置成5000秒(约83分钟),跑完后查看三张关键波形:电池端电压、充电电流、SOC。
我实际跑出的波形大概是这样:起始阶段,电流立刻被拉到1A,电压从3.6V左右缓慢上升,这一段电流线是一条水平直线,非常典型;随着电压接近4.2V,电流开始出现下降趋势,这是CC模式在退出;切换到CV模式后,电压基本稳定在4.2V,电流按指数规律逐渐衰减;当电流降到0.1A附近,仿真触发充电完成信号,充电流程结束。
观察SOC曲线,会看到SOC在CC阶段几乎线性上升,到了CV阶段上升速度大幅放缓。为什么?CV阶段电流越来越小,同样时间内充入的电量自然减少,所以SOC变化曲线越来越平。这在真实充电器中是完全一致的表现,说明模型的核心规律是符合物理直觉的。
4.3 恒流恒压切换瞬间的局部放大
如果只拉远看波形,会觉得切换非常平滑,但放大到切换点附近看,可能会发现电压存在几十毫伏的超调,或者电流有一个短暂的下冲。这跟PI参数和切换策略有很大关系。
我在一排实验中试过几种情况:如果恒流PI的积分项太强,切换前电流误差虽小但积分量已经很大,切换瞬间占空比输出会跳变,导致电压尖峰;如果恒压PI的Kp太大,切换后电压会产生衰减振荡。最终通过无扰切换+适当减小恒压Kp解决了问题,切换点的电压尖峰从约150mV降到了30mV以下。
提示:判断切换逻辑是否合理,不要只看最终波形,一定要放大切换点局部看电压电流轨迹。理想情况是:切换前后电压连续、电流平滑过渡,没有尖锐的阶梯突变。
4.4 不同参数组下的对比实验
为了验证模型的鲁棒性,我还跑了几组对比实验。
第一组改变充电倍率,把1A改成2A(即1C充电),充电时间明显缩短,但恒压阶段电流衰减的起始点更早,因为欧姆内阻导致的压降更大了。这说明高倍率充电时,电压会更快触顶,恒流阶段能充入的电量占比降低,整体充电效率反而可能下降。
第二组改变SOC初值,从20%改为50%,结果是恒流充电阶段的起始电压更高,CV阶段维持时间变长,总充电时长略短。这个现象也符合常识:高SOC起点意味着电池离满电更近,有效充电窗口变短。
第三组调整截止电流,从0.1A改到0.2A,充电提前结束,最终SOC只充到97%左右。这说明截止电流的设定直接决定了充电完成时的实际电量,如果追求满充,应该把截止电流设得更小。
5. 常见问题与排查技巧实录
5.1 代数环与仿真变慢的解法
自己从零搭模型最容易碰到的就是代数环。代数环出现在:某个信号直接绕过动态模块,在当前仿真步内形成瞬时反馈。比如我把电压采样直接经过增益模块又回接到受控电压源的参考端,Simulink就会报代数环警告,求解速度明显变慢,甚至可能不收敛。
解决代数环最有效的办法是:在反馈路径上人为插入一个小延迟或低通滤波器,打破瞬时依赖关系。我那次是在电流反馈通路上加了一个截止频率1000Hz的滤波模块,代数环就解开了,而且对控制性能影响极小。
5.2 开关频率过高导致波形“毛刺”怎么处理
PWM载波频率设得太高(比如50kHz以上)时,即使定步长够小,采样到的电流波形也会充满毛刺。这本质上是仿真步长和PWM载波周期的采样同步问题。
我的处理办法是先降低PWM载波频率到10kHz,把仿真步长设为1e-6秒,并且开启Simulink的Pulse Generator参数中的“基于采样时间的脉冲”选项,确保每个载波周期内都有足够的采样点。如果模型已经很大、仿真速度很吃紧,可以把载波频率故意降到5kHz,只关注控制行为,不追求开关细节。
5.3 PI参数不稳定的调参实战
我早期在恒流阶段遇到了一个典型的PI振荡问题:电流不是平直的水平线,而是以10kHz的频率上下乱抖,幅度还很大。后来排查发现,PI输出没有做限幅,占空比偶尔超出[0.05, 0.95]区间,导致PWM发波异常。加了饱和限幅后,波形立刻稳定下来。
还有一个容易被忽略的坑:两个PI控制器共用一个占空比输出通道时,CC和CV的PI参数可能互相影响。我最后采用的做法是mode switch变量作为乘法器,把不工作的PI输出乘以0,再与工作的PI输出相加,这样两个PI物理上隔离,互不干扰。
5.4 锂电池SOC估算不更新的排查思路
有一次拉仿真发现SOC一直停在初值53.2%不动,排查后找到原因:我把SOC积分器的初始值设置在了积分器的External initial condition端口,但信号线没接对,导致积分器始终从固定初值开始积分。这个是粗心问题,但很典型。
另外提醒一下:安时积分法在实际应用中会有累计误差,仿真中虽然不会漂移,但如果以后做硬件在环,需要配合卡尔曼滤波或其他SOC估计算法,才能保证长时间运行的精度。
6. 模型扩展方向与个人经验总结
这个模型真正跑通以后,能做的事情其实远超教学演示。我在实际工作中基于这套CC-CV模型做了几个延伸改造,这里简单分享一下。
一是加入温度模型。锂电池的充电性能受温度影响很大,低温下需要降低充电电流,防止析锂;高温下需要降低截止电压,防止热失控。在现有模型上,把内阻R0和容量做成温度查表函数,再根据发热功率和散热系数计算电芯温升,就能模拟一个完整的“充电-发热-降温”耦合过程。
二是加入电池老化模型。电池循环寿命与充放电深度、温度、充电倍率密切相关。把当前模型的可用容量设为一个随循环次数衰减的函数,可以观察老电池在相同充电策略下的充电时间延长现象,这对BMS的均衡策略和充电策略自适应调节很有价值。
三是把充电策略从普通CC-CV改成多级恒流充电或脉冲充电。你只需要把控制子系统的给定逻辑改为分段给定,就能对比不同策略下的充电时间、充电效率和温度上升。
最后再聊聊个人的一点实操体会。做仿真最忌讳的就是一上来就搭复杂模型。我踩过几次坑之后,习惯是把模型拆成最小闭环:先让电池开路电压固定、内阻固定,搭一个最简单的受控电流源充电闭环,确认反馈和控制链路没问题,再逐步引入OCV-SOC查表、RC极化、PWM开关、模式切换。每加一个环节就仿真一次、看一次波形,这样出问题时定位特别快。整套模型跑下来,不仅是把CC-CV原理验证了一遍,更重要的是对“电压-电流-SOC-时间”这四者的动态交互有了一种直觉。这种直觉,是只看电路图或只背公式得不到的。希望这份模型拆解能给正在做电池仿真的你一些启发。