
🎬 渡水无言 :个人主页渡水无言
❄专栏传送门 : 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》
❄专栏传送门 : 《freertos专栏》 《STM32 HAL库专栏》《linux裸机开发专栏》
❄专栏传送门 :《产品测评专栏》 《Ai智能体专栏) 《ROS开发专栏》
❄专栏传送门 :《BMS专栏》
⭐️流水不争先,争的是滔滔不绝
📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生
| 省级优秀毕业生获得者 | csdn新星杯TOP1 | 半导纵横专栏博主 | 211在读研究生
在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连
目录
[二、任务主入口 BMS_AnalysisTaskEntry](#二、任务主入口 BMS_AnalysisTaskEntry)
[三、基础电气参数计算 BMS_AnalysisEasy](#三、基础电气参数计算 BMS_AnalysisEasy)
[五、SOC 计算](#五、SOC 计算)
前言
在前文中,我们依次讲解了 BMS_MonitorTask 电池监控任务、BMS_ProtectTask 电池保护任务,这两大模块完成了电池原始数据采集与安全防护。
本文继续拆解整套 BMS 的第三大核心任务:BMS_AnalysisTask 电池状态分析任务。
该任务基于监控任务上报的电压、电流、温度原始数据,完成基础电气参数计算、温度容量校准、SOC 剩余电量估算、剩余容量统计等核心算法。
一、任务整体定位与调用关系
BMS_AnalysisTask(电池分析任务)是 BMS 的算法计算核心,运行在监控、保护任务之后,主要职责:
计算电芯最大 / 最小电压、单体压差、电池平均电压、实时功率等基础参数;
根据环境温度对电池额定容量做动态校准;
采用 开路电压法 + 安时积分法 双算法计算 SOC 剩余电量与剩余容量;
上电完成容量、SOC 初始值校准;
输出分析后的数据,供给上位机显示、整机逻辑决策使用。
上下游依赖
数据源:依赖 BMS_MonitorTask 采集的电压、电流、温度数据;
联动模块:数据供给保护任务、均衡任务、串口 / 485/CAN 上报任务使用;
运行系统:基于 RT-Thread 实时操作系统,周期轮询执行。
完整函数调用栈
cpp
BMS_AnalysisInit // 分析任务初始化 & 创建线程
└── BMS_AnalysisTaskEntry // 任务主入口(死循环)
├── BMS_AnalysisCapAndSocInit // 上电容量、SOC初始化校准
├── BMS_AnalysisEasy // 基础参数计算(压差、平均电压、实时功率)
├── BMS_AnalysisCalCap // 电池容量计算 & 温度校准
│ └── BMS_AnalysisTempCal // 温度补偿算法
└── BMS_AnalysisSocCheck // SOC综合计算
├── BMS_AnalysisOcvSocCalculate // 开路电压法(OCV)
└── BMS_AnalysisAHSocCalculate // 安时积分法(AH)
二、任务主入口 BMS_AnalysisTaskEntry
代码如下所示:
cpp
static void BMS_AnalysisTaskEntry(void *paramter)
{
// 上电执行一次:容量、SOC初始校准
BMS_AnalysisCapAndSocInit();
while(1)
{
BMS_AnalysisEasy(); // 基础参数计算
BMS_AnalysisCalCap(); // 容量+温度校准
BMS_AnalysisSocCheck(); // SOC综合计算
osDelay(ANALYSISI_TASK_PERIOD); // 1s周期延时
}
}
上电仅运行一次BMS_AnalysisCapAndSocInit,完成初始容量、SOC标定;
进入1秒周期死循环,依次执行基础计算 → 容量温度校准 → SOC 计算;
整体时序稳定,符合电池参数变化慢的特性。
三、基础电气参数计算 BMS_AnalysisEasy
该函数负责简单四则运算类参数,读取监控任务的原始电压、电流,计算压差、平均电压、实时功率,逻辑简单、执行效率高。
cpp
static void BMS_AnalysisEasy(void)
{
uint8_t index;
// 1. 电芯最大电压差(均衡判断核心依据)
BMS_AnalysisData.MaxVoltage = BMS_MonitorData.CellData[BMS_GlobalParam.Cell_Real_Num - 1].CellVoltage
- BMS_MonitorData.CellData[0].CellVoltage;
// 2. 整组电芯平均电压
BMS_AnalysisData.AverageVoltage = 0;
for (index = 0; index < BMS_GlobalParam.Cell_Real_Num; index++)
{
BMS_AnalysisData.AverageVoltage += BMS_MonitorData.CellData[index];
}
BMS_AnalysisData.AverageVoltage /= BMS_GlobalParam.Cell_Real_Num;
// 3. 电池实时功率 P = 总电压 × 电流
BMS_AnalysisData.PowerReal = BMS_MonitorData.BatteryVoltage * BMS_MonitorData.BatteryCurrent;
// 4. 单体最高/最低电压
BMS_AnalysisData.CellVoltMax = BMS_MonitorData.CellData[BMS_GlobalParam.Cell_Real_Num - 1].CellVoltage;
BMS_AnalysisData.CellVoltMin = BMS_MonitorData.CellData[0].CellVoltage;
}
四、电池容量与温度校准
锂电池容量受温度影响极大:低温容量衰减、高温加速老化。本模块实现温度动态补偿容量。
入口函数
cpp
static void BMS_AnalysisCalCap(void)
{
BMS_AnalysisTempCal();
}
温度校准核心 BMS_AnalysisTempCal
额定容量 → 温度修正后实际容量 → 计算剩余容量
cpp
static void BMS_AnalysisTempCal(void)
{
static int16_t LastTemp = 0;
uint8_t Ratio;
uint16_t RateTemp;
int16_t MinTemp = BMS_MonitorData.CellTemp[0] * 10;
// 温度数据无效,直接退出
if (BMS_MonitorData.CellTempEffectiveNumber == 0)
{
return;
}
// 温度变化小于1℃,不重新校准(防抖)
if( abs(MinTemp - LastTemp) < 10 )
{
return;
}
LastTemp = MinTemp;
// 分段设置温度补偿系数
if (MinTemp >= 250) Ratio = 1;
else if (MinTemp >= 100) Ratio = 2;
else if (MinTemp >= 0) Ratio = 3;
else if (MinTemp >= -200) Ratio = 4;
else if (MinTemp >= -300) Ratio = 5;
else Ratio = 6;
// 计算容量折算率
RateTemp = 1000 + Ratio * (MinTemp - 250);
// 限制折算率上下限
if(RateTemp > TEMP_CAP_RATE_LIMITH_HIGH ) RateTemp = TEMP_CAP_RATE_LIMITH_HIGH;
if(RateTemp < TEMP_CAP_RATE_LIMITL_LOW ) RateTemp = TEMP_CAP_RATE_LIMITL_LOW;
// 动态实际容量 = 额定容量 × 温度折算率
BMS_AnalysisData.CapacityReal = BMS_AnalysisData.CapacityRated * RateTemp / 1000;
// 剩余容量 = 实际容量 × SOC
BMS_AnalysisData.CapacityRemain = BMS_AnalysisData.CapacityReal * BMS_AnalysisData.SOC;
}
如果新检测到的温度和上一次相差一度以上,则更新,如果没有则不校准。
校准也是按照分段的,某一段对应的斜率不一样,进而更符合实际情况。
五、SOC 计算
结合完整任务执行流程,梳理 SOC 相关代码的层级关系:
cpp
BMS_AnalysisTaskEntry (分析任务主循环,1s周期运行)
├─ BMS_AnalysisEasy // 基础电压、功率计算
├─ BMS_AnalysisCalCap // 温度+容量校准
└─ BMS_AnalysisSocCheck 【SOC计算总入口】
├─ BMS_AnalysisOcvSocCalculate // 开路电压(OCV)算法
└─ BMS_AnalysisAHSocCalculate // 安时积分(AH)算法
注意:上电会进行初始化
BMS_AnalysisTaskEntry (任务启动仅执行一次)
└─ BMS_AnalysisCapAndSocInit // 上电SOC初始化(单独逻辑,不经过SocCheck)
BMS_AnalysisSocCheck
该函数是运行阶段 SOC 计算的唯一入口,任务每 1 秒轮询一次,依次调用 开路电压法 和 安时积分法 两套算法,根据电池当前工作模式自动选择生效逻辑。
上电瞬间:SOC 由 BMS_AnalysisCapAndSocInit 函数完成初始化(直接查表),不经过本入口;
设备正常运行(待机 / 充电 / 放电 / 睡眠):
所有 SOC 刷新、修正、计算,全部由 BMS_AnalysisSocCheck 驱动。
cpp
// soc检查(SOC计算总入口)
static void BMS_AnalysisSocCheck(void)
{
BMS_AnalysisOcvSocCalculate(); // 开路电压法计算/校准SOC
BMS_AnalysisAHSocCalculate(); // 安时积分法计算SOC
}
代码结构极简,采用串行执行双算法 的设计,两套算法各司其职、互相补充,是嵌入式 BMS 经典的OCV + 安时积分组合方案。
1. BMS_AnalysisOcvSocCalculate(开路电压法)
触发条件:仅当系统处于睡眠模式(BMS_MODE_SLEEP) 时执行。
核心作用:电池长期静置、电流近似为 0,电芯电压回归真实开路电压,用于修正安时积分的累积误差。
执行细节:等待电压稳定延时 → 读取单体电压 → 查表换算 SOC → 更新剩余容量。
非睡眠模式:该函数内部逻辑不执行,直接空运行。
2. BMS_AnalysisAHSocCalculate(安时积分法)
触发条件:待机、充电、放电 全工况都会执行,是动态工况下的主力算法。
核心作用:基于实时电流做积分运算,动态更新剩余容量与 SOC。
原理:剩余容量变化量 = ∫电流 × 采样时间
实时积分逻辑:BMS 每隔固定周期采集回路电流,把每一段周期内的电量变化累加 / 扣减,实时更新电池剩余容量;再用「剩余容量 ÷ 电池可用实际容量」算出 SOC。
工程实现
任务周期 200ms/1s,把毫秒级时间换算成小时,计算单次充放电电量;
充电:剩余容量 += 本次增量;放电:剩余容量 -= 本次消耗;
限制边界:剩余容量最大不超额定容量、最小不为 0。
充电模式:累加容量,SOC上升;
放电模式:扣减容量,SOC下降;
待机模式:根据电压极值强制锁定SOC(满电 = 100%、欠电 = 0%)。
补充:该算法实时性强,但长时间运行会产生积分漂移,依赖开路电压法定期校准。
| 系统工作模式 | 开路电压法 | 安时积分法 | 最终 SOC 来源 |
|---|---|---|---|
| 睡眠模式 | 执行(校准) | 执行 | 以 OCV 查表结果为准,修正积分误差 |
| 充电模式 | 不执行 | 执行(主力) | 安时积分累加容量 |
| 放电模式 | 不执行 | 执行(主力) | 安时积分扣减容量 |
| 待机模式 | 不执行 | 执行(边界锁定) | 电压极值强制 SOC 为 0/100% |
以完整上电→运行流程为例:
系统上电 → 分析任务启动 → 执行BMS_AnalysisCapAndSocInit,查表得到初始 SOC;
进入任务 1s 主循环 → 每次循环调用BMS_AnalysisSocCheck;
设备充电:仅安时积分运行,持续累加容量;
设备停机静置 → 进入睡眠模式:开路电压法启动,修正长期积分误差;
再次开机放电:安时积分继续工作,SOC 正常下降。
总结
BMS_AnalysisTask 是整套 BMS 的算法核心,承接监控任务的原始数据,完成参数运算、温度补偿、SOC 与容量计算。
结合前文**监控任务、保护任务:**数据采集 → 安全保护 → 算法分析 → 上位上报。