Skip to main content

Command Palette

Search for a command to run...

● BMS工程代码全面知识提炼 — 博客专题写作提纲

Updated
9 min read

专题一:BMS系统架构总览

博客标题建议:《工业级BMS系统架构设计:从硬件选型到软件分层》

提纲要点:

  1. BMS在储能系统中的定位 :

    1. - BMS、PCS、EMS三者关系:

    2. - BMU(Battery Management Unit)与BSMU(Battery System Management Unit)的层级关系

    3. - 本工程:BMU负责单体采集,通过CAN上报BSMU

  2. 硬件平台选型分析

    1. - 主控:NXP S32K146(ARM Cortex-M4F,112MHz,车规级MCU)

    2. - 为什么选车规MCU:AEC-Q100认证、宽温度范围、功能安全

    3. - 片上资源盘点:FlexCAN×3、LPUART×3、LPSPI×4、LPI2C×2、FTM×8、ADC×2

  3. 外围芯片生态

    1. - AFE:LTC6813-1(18S,菊花链SPI,精度±1.2mV)

    2. - 精密库仑计:LTC2949(高精度电流/电压/温度/功率/能量积分)

    3. - SBC电源管理:NXP FS6503(ASIL-D,看门狗,安全状态机)

    4. - 外部EEPROM:M24512(512Kbit,I2C,参数持久化)

    5. - 外部Flash:SST26VF064(64Mbit,SPI,历史记录波形存储)

    6. - RTC:EPSON RX8010(I2C,断电保持时间)

  4. 软件分层架构

    1. Application Layer ← 业务逻辑(SOC/SOH/故障诊断/充放电策略)

    2. Function Layer ← 功能模块(采样/计算/状态机)

    3. BSP Layer ← 板级支持包(HAL适配,初始化序列)

    4. Driver Layer ← 设备驱动(LTC6813/FS65/M24512等)

    5. SDK Layer ← NXP SDK(Generated_Code,外设寄存器抽象)

    6. Hardware Layer ← S32K146 + 外围芯片

  5. 模块间通信设计

    1. - 全局共享内存(GroupInfo.c/GroupPara.c)

    2. - API函数隔离(GetXXXAPI/SetXXXAPI模式)

    3. - 无消息队列、无信号量的轻量级设计选择与代价


专题二:FreeRTOS在BMS中的工程化应用

博客标题建议:《FreeRTOS软件定时器+任务混合架构:BMS实时调度设计》

提纲要点:

  1. 为什么BMS需要RTOS

    1. - 多路采样并发(电压/温度/电流/高压独立任务)

    2. - 实时性要求:5ms控制周期,CAN收发不能阻塞采样

    3. - 确定性执行:故障诊断必须在规定时间窗口内完成

  2. 本工程调度架构设计

    1. - 10个软件定时器(Timer):5ms/10ms/50ms/100ms/200ms/300ms/400ms/500ms/1000ms/2000ms

    2. - 6个独立任务(Task):CellSample/HigSample/LowSample/CANSend/CANRcv/UARTRcv

    3. - 定时器回调在Timer Service Task中执行,与普通任务抢占

  3. 10ms任务的二级调度技巧

    1. static u8 sTime = 0; switch(sTime) { case 0: CurrLimCalcTask(); CurrLimFallTask(); break; case 1: CheckVoltCharaTask(); CheckTempCharaTask(); break; // ...共10个case,每个100ms执行一次 } sTime = (sTime+1) % 10;

    2. - 意义:100ms周期任务分散在10个10ms时隙,避免同时执行造成抖动

    3. - 工程实践:比直接用100ms定时器更灵活,便于调整各子任务时序依赖

  4. 阻塞式采样任务设计

    1. - CellInfoSampleTask:12状态机 + OSIF_TimeDelay阻塞

    2. - 状态机设计的优势:不阻塞调度器,通过delay主动让出CPU

    3. - 与轮询方式对比:减少CPU占用,适合长耗时外设操作(SPI菊花链)

  5. FreeRTOS关键API在BMS中的使用

    1. - xTimerCreate/xTimerStart:软件定时器创建与启动

    2. - xTaskCreate:任务优先级规划(采样 > CAN > UART)

    3. - OSIF_TimeDelay:NXP SDK对vTaskDelay的封装

    4. - vTaskStartScheduler:调度器启动点

  6. RTOS诊断:OSDiagTimerAddTask

    1. - 检测各定时器实际执行时间是否超期

    2. - 嵌入式系统健康监控实践


专题三:锂电池单体电压采集——LTC6813工程实践

博客标题建议:《LTC6813菊花链采样:18S×32从控的工程级实现》

提纲要点:

  1. LTC6813芯片架构

    1. - 18路差分电压测量,±1.2mV精度

    2. - 菊花链(Daisy-chain)SPI:多个芯片串联,单SPI口控制32片

    3. - 隔离通信:LTC6820作为isoSPI转换器

    4. - 内置ADC:7kHz模式18路扫描时间<3.9ms

  2. 双链路设计(本工程)

    1. - LTC6820-1 + LTC6820-2:两路独立isoSPI,CS1/CS2片选切换

    2. - 冗余设计意义:单链路故障仍可采样

  3. 采样状态机详解(12状态)

    1. State 0: 更新均衡需求 → State 1/2

    2. State 1: ADC清零(有均衡停止前序)

    3. State 2: 启动ADC转换(7kHz模式)

    4. State 3/4/5: 分批读取寄存器A/B、C/D、E/F

    5. State 6: 校验并处理电压值

    6. State 7/8/9: 清零GPIO ADC → 启动GPIO ADC → 读取温度

    7. State 10: 处理温度值

    8. State 12: 更新均衡控制

  4. ADC读取分批策略

    1. - 一次采样读6组寄存器(ADCA/B/ADCC/D/ADCE/F),每读一次等待bsuNum × LTC_RD_AD_T

    2. - 原因:菊花链数据通过每个芯片中继,从控越多延迟越大

  5. 电池位置补偿(硬件寄生电阻补偿)

    1. 首节电池: +3.0mV(CELF_COMP_VOLT)

    2. 末节电池: +2.5mV(CELE_COMP_VOLT)

    3. 中间电池: +2.3mV(CELM_COMP_VOLT)

    4. - 原理:PCB走线阻抗、均衡电阻导致测量偏差,通过固定补偿修正

  6. 14S特殊处理(CATL/标准PACK)

    1. - 第8路通道保留给参考电压,跳过:cell_num = cell_Id < 7 ? cell_Id : cell_Id - 1
  7. 采样异常处理

    1. - noVSampCounter:连续异常计数,≥20次才记录故障

    2. - 异常时重新初始化LTC6813

    3. - 全为0时置Clr,触发上层诊断


专题四:NTC热敏电阻温度采集算法

博客标题建议:《NTC热敏电阻温度测量:从电压到℃的完整工程链路》

提纲要点:

  1. NTC工作原理

    1. - B值公式:R = R₀ × exp(B × (1/T - 1/T₀))

    2. - 与温度负相关,灵敏度高(低温更明显)

    3. - 10K/47K/100K不同阻值的应用场景

  2. 硬件电路(分压器)

    1. - 电池温度:10K NTC + 100kΩ上拉,3.0V基准

    2. - 均衡温度:47K NTC + 下拉(冷极/热极两种)

    3. - AFE直接读取GPIO引脚电压(1mV精度)

  3. 电压→电阻转换

    1. // 10K NTC,100kΩ上拉,3.0V基准 R = Vdata * 10000 / (3000 - Vdata)
  4. 查表法与插值 - 166元素查找表,覆盖-41°C到125°C,步长1°C - 二分查找 + 中点插值:if(data <= (tab[i] + tab[i-1]) / 2) return i; else return i-1; - 四种不同电池型号的NTC表(宁温/CATL 240Ah/CATL 280Ah液冷/REPT标准)

  5. 均衡温度特殊处理 - GPIO1/GPIO2两路均衡温度,硬件存在非线性偏差 - 分段线性校正(KB修正): // GPIO1,13°C以上 corrTemp = (9569 * temp - 1639) / 10000; // GPIO2,低温段另一组系数 corrTemp = (10168 * temp - 17877) / 10000; - 意义:通过实测数据拟合修正,弥补NTC批次一致性差问题

  6. 多项目NTC表编译期选择 - #if(1 == PRJ_PARA_NUM_INFO) ... #elif ... #else - 同一份代码支持多个客户项目,编译配置宏切换


专题五:安时积分法(库仑计)——SOC核心算法实现

博客标题建议:《安时积分法完整工程实现:单位换算、累积误差与修正策略》

提纲要点:

  1. 安时积分基本原理 - SOC(t) = SOC(0) - (1/C_rated) × ∫I dt - 离散化:每个采样周期 ΔCap = I × Δt - 优势:实时性好,跟踪快速变化 - 劣势:误差累积,需要初始值校正

  2. 本工程实现的单位级联 输入:电流 I(单位:10mA),时间 t(单位:1ms) 累积器:chgCap10ma1ms(10mA·ms) 换算:1 mAh = 3600 mA·s = 3,600,000 mA·ms = 360,000 × 10mA·ms 进位:每积累360,000个10mA·ms,进位1 mAh 上层单位:mAh → Ah - 为什么用整数而非浮点:嵌入式无FPU时效率,或节省FPU给更高优先级计算

  3. 充放电方向处理 changCap1ma1h += chgCap1mah; // 充电增量(正方向) changCap1ma1h -= dhgCap1mah; // 放电减量(负方向) - changCap1ma1h:本次状态转换的净变化量,用于SOC缓慢变化算法

  4. 能量积分的并行实现 - Energy(Wh) = ∫V × I dt - 单位:mW·ms → mWh → Wh → 0.1kWh - 换算常数:1 Wh = 3,600,000 mW·ms

  5. 积分触发时机 - 采样完成标志位(VSampFinFlag/TSampFinFlag)置位后触发 - 确保积分使用已稳定的采样值

  6. 累积误差来源与影响 - 电流传感器零漂(Offset误差) - ADC量化误差 - 采样周期不均匀(OS调度抖动) - 温度影响电流传感器精度


专题六:SOC多策略融合修正算法

博客标题建议:《工程级SOC算法:安时积分+电压修正+端点标定的完整方案》

提纲要点:

  1. 容量形式(Capacity Form)设计 CAP_ZERO_POINT = 5000 mAh(零点偏移,避免负数) nowCap = 实际当前容量 + CAP_ZERO_POINT SOC = (nowCap - lowCap) * 10000 / (allCap - lowCap) - 为什么需要零点偏移:过放场景下nowCap可能比lowCap还小(负值),用偏移量统一处理

  2. 四个容量变量的语义 - baseCap:零SOC对应容量(死区容量) - topCap:100% SOC对应容量 - nowCap:当前容量(安时积分维护) - remCap:剩余可放电容量(理论最大放电量) - allCap = topCap - baseCap:有效容量

  3. 初始SOC建立 - 从EEPROM读取上次存储SOC - 上电5秒内不信任采样值,强制初始化期

  4. 五类电压修正触发条件

触发条件 修正动作
过充保护触发(VH1+VH2同时) 强制SOC→100%
过放保护触发(VL1+VL2同时) 强制SOC→0%
充电高压限制(VH2) SOC收敛→99%
放电低压限制(VL2) SOC收敛→3%
静置足够时间 + 电压极端区间 电压查表修正
  1. 静置修正(Open Circuit Voltage Correction) - 条件:空闲状态(CURR_IDLE)持续SOC_SLOW_CORR_IDLE_T时间 - 策略:最大电压低于阈值时下调SOC,最小电压高于阈值时上调SOC - 本质:利用OCV-SOC曲线的单调性,在静置后强制SOC与电压对应

  2. 充放末端修正 - 充电末端:最大电压≥4.15V且SOC<95% → 强制SOC上调 - 放电末端:最小电压≤3.0V且SOC>5% → 强制SOC下调 - 工程意义:防止SOC显示值在临界状态给出错误判断

  3. EEPROM持久化策略 - SOC变化≥0.1%时写EEPROM - 充放电状态转换时强制写 - 容量值(nowCap)实时写(每次积分进位1mAh时)


专题七:SOC缓慢显示算法(用户体验工程)

博客标题建议:《BMS SOC显示平滑算法:让百分比变化符合用户直觉》

提纲要点:

  1. 为什么需要显示平滑 - 安时积分值跳变(ADC噪声/电流噪声) - 保护触发时SOC强制修正导致跳变 - 用户看到SOC像进度条一样跳动体验差

  2. 速度自适应的单向跟踪 - 充电时SOC只能增加(慢慢追上算法值) - 放电时SOC只能减少 - 突变量 = 实际变化量 + 步进量(stepSoc)

  3. 接近端点时加速显示 充电侧(SOC→100%): SOC > 97.5%: 5秒追完剩余量(快速) SOC > 95%: 15秒追完 SOC > 93%: 20秒追完 SOC > 90%: 30秒追完 SOC > 80%: 60秒追完 SOC < 80%: 120秒追完(最慢) - 同样逻辑用于放电侧(镜像处理)

  4. 端点锁定机制 - SOC≥99%时锁定在99%(不显示100%,除非触发满电保护) - SOC≤1%时锁定在1%(不显示0%,除非触发欠压保护) - 意义:给用户留有余量感

  5. 强制修正的显示处理 - CorrGDisplaySocByUser():直接覆写显示值,不经过缓慢变化 - 过充/过放保护触发:立即显示100%/0%


专题八:SOH健康状态算法

博客标题建议:《锂电池SOH计算:容量实测法与循环计数法的双重验证》

提纲要点:

  1. SOH的定义与意义 - SOH = 当前最大容量 / 额定容量 × 100% - 反映电池老化程度,指导换电/维护决策

  2. 方法一:容量实测法 capSoh = GetGroupTotalCapAPI() * 10 / GetGroupRatedCapAPI() // TotalCap由实测充放电循环确定 - 优势:直接测量,准确 - 劣势:需要完整充放电循环,数据收敛慢

  3. 方法二:循环计数线性衰减模型 timSoh = 1000 - (fadeCycle * 200 / ratedCycle) // 假设:寿命终止时SOH=80%(线性衰减) - fadeCycle:实际循环次数 - ratedCycle:额定循环寿命(参数表读取) - 优势:无需等待完整循环

  4. 双方法融合策略 if |capSoh - timSoh| < 50(5%): 采用循环计数模型(更稳定) else: SOH = (capSoh + timSoh) / 2 SOH ≤ 上次SOH(防止反弹) SOH ≥ 上次SOH - 5(防止单次大跌)

  5. SOH更新时机 - 每次循环计数变化后触发一次更新 - 同步写入EEPROM

  6. SOH的工程局限性 - 温度影响容量(低温容量减小不代表SOH降低) - 倍率影响容量(大电流放电容量低) - 本工程未显式进行温度/倍率补偿的分析


专题九:卡尔曼滤波器理论与BMS应用

博客标题建议:《卡尔曼滤波估算SOC:从理论推导到嵌入式实现》

▎ 注:本工程未实现卡尔曼滤波,但这是BMS领域重要算法,以下为专题博客内容规划

提纲要点:

  1. 为什么安时积分需要卡尔曼辅助 - 开环积分误差不收敛 - 传感器噪声影响精度 - 卡尔曼:最优线性无偏估计

  2. 卡尔曼滤波五大方程

    1. 预测阶段:

      1. x̂⁻(k) = A·x̂(k-1) + B·u(k) (状态预测)

      2. P⁻(k) = A·P(k-1)·Aᵀ + Q (协方差预测)

    2. 更新阶段:

      1. K(k) = P⁻(k)·Hᵀ / (H·P⁻(k)·Hᵀ + R) (卡尔曼增益)

      2. x̂(k) = x̂⁻(k) + K(k)·(z(k) - H·x̂⁻(k)) (状态更新)

      3. P(k) = (I - K(k)·H)·P⁻(k) (协方差更新)

3. BMS中的状态变量设计

- 状态向量:x = [SOC, 极化电压Vp]ᵀ

- 观测量:z = 端电压 Vt

- 模型:Vt = OCV(SOC) - Vp - I·R0 4. 扩展卡尔曼(EKF)的必要性 - OCV-SOC关系是非线性的 - 需要在工作点线性化(雅可比矩阵) 5. 嵌入式实现注意事项 - 矩阵运算的定点化 - Q/R噪声协方差的调参 - 计算量评估:2×2矩阵求逆 vs ARM Cortex-M4F性能 6. 与本工程方案对比 - 本工程:安时积分 + 多点电压校正(工程化、易调试) - 卡尔曼:理论最优、动态收敛(计算量大、调参复杂)


专题十:故障诊断系统设计

博客标题建议:《BMS故障诊断:两态状态机+滤波延迟的可靠故障检测》

提纲要点:

  1. 两态故障状态机 - eErr_A:正常态 - eErr_B:故障态 - 故障确认:需要持续超过滤波时间(防抖) - 故障恢复:需要持续正常超过恢复时间

  2. 故障分类体系 电压类:CEL_VH1/VH2(过压一/二级)、CEL_VL1/VL2(欠压一/二级) 温度类:CEL_TH1/TH2(高温)、CEL_TL1(低温) 电流类:过充电流、过放电流 采样类:SAMP_EXP(AFE异常)、SAMP_VOFF(电压断线)、SAMP_TOFF(温度断线) 通信类:INT_COFF(内部CAN)、CELL_MISS(从控丢失) 绝缘类:INS_LOW(绝缘下降) 继电器类:主继电器粘连

  3. 通信看门狗机制 - 每个从控(BSU)有计数器,每秒复位 - CAN消息到达时递增 - 1秒内未收到N帧 → 触发通信故障

  4. AFE采样错误位域 - u8 errFlag[MAX_BSU_NUM]:位0=电压异常,位1=温度异常,位2=AFE通信异常 - 按从控粒度记录,便于定位具体节点

  5. 继电器粘连检测 - 主继电器吸合前:检测主正高压是否为0(粘连则有电压) - 主继电器断开后:检测主正高压是否降为0(粘连则仍有电压) - 电流辅助:切换瞬间无电流变化也可判断粘连

  6. 绝缘监测(接地故障检测) - 正负极对地阻抗测量 - 主动注入法 vs 被动测量法 - 阈值:通常<500Ω/V触发报警

  7. 诊断结果对SOC算法的保护 - 采样异常时:不更新电压/温度 - 通信故障时:停止均衡 - 过压/过放时:强制SOC修正


专题十一:被动均衡策略工程实现

博客标题建议:《锂电池被动均衡:LTC6813放电均衡的完整控制逻辑》

提纲要点:

  1. 均衡原理 - 被动均衡:通过放电电阻将高电压单体的能量以热量形式耗散 - LTC6813:每节电池对应一个内部开关,控制寄存器bit位对应单体

  2. 均衡请求信息更新 sLTC6813PasBalanCmd[i] = GetGroupVoltPasBalanReqState(i); // 14S特殊处理:跳过第8路(参考电压) sLTC6813PasBalanCmd[i] = reqState & 0x007f | ((reqState & 0x3f80) << 1);

  3. 均衡开/停条件 - 开始:有均衡请求(sLTC6813PasBalanReqState > 0) - 停止条件(任一触发):

    • 无均衡请求

    • 均衡时间达到最大值(BalSamT × 100ms)

    • 最大单体电压≥平台电压(CellPlaUpV,0.5周期)

    • 最大单体电压接近告警(CellPlaUpV - 30mV)

  4. 均衡期间的采样处理 - 均衡开启时:不更新电压显示值(均衡电流引起电压偏差) - sLTC6813PasBalanCtrlState:记录当前是否有均衡开启 - 判断条件:(sLTC6813PasBalanCtrlState == 0) || (cmd[cell_Ic] & (1 << cell_Id)) == 0

  5. 均衡寄存器写入(支持18S) // 配置寄存器A:cell1-8(低8位)、cell9-12(中4位) cfgA[4] = cmd & 0x00FF; // S1-S8 cfgA[5] = (cmd & 0x0F00) >> 8; // S9-S12 // 配置寄存器B:cell13-16(高4位)、cell17-18 cfgB[0] = ((cmd & 0xF000) >> 8) | LTC_GPIO_CT_AD_BIT; cfgB[1] = (cmd >> 16) & 0x03; // S17-S18

  6. 主动均衡与被动均衡对比(博客延伸) - 被动:简单,有热耗散,适合低均衡需求 - 主动:复杂(LLC/Buck-Boost),效率高,成本高


专题十二:CAN总线在储能BMS中的应用

博客标题建议:《储能BMS CAN通信架构:3路CAN的分工与协议设计》

提纲要点:

  1. 本工程CAN总线规划 CAN0:外部通信(BMU↔PCS/BSMU,标准协议/CATL协议) CAN1:内部通信(BMU↔BSU,采样数据上报) CAN2:辅助通信(特殊设备)

  2. CAN任务架构 - BSPCANSendTask:独立高优先级任务,从消息队列取数据发送 - BSPCANRcvTask:独立高优先级任务,接收后分发给各模块 - 5ms Timer:CANLibHandleTask_API()定时触发CAN库处理(心跳/超时检测)

  3. CAN消息分发(BSPUserHook.c) switch(msgId) { case PCS_MSG_ID: // PCS上/下电命令 case SOC_SYNC_ID: // SOC同步 case CHG_MSG_ID: // 充电协议 case CATL_MSG_ID: // CATL专属协议 }

  4. 通信协议层次 - 物理层:CAN 2.0B,标准帧/扩展帧 - 数据链路层:FlexCAN驱动(NXP SDK) - 应用层:自定义消息格式(ID + 8字节数据)

  5. CAN通信故障处理 - Bus-off检测:物理层中断 - 消息超时:应用层看门狗计数 - 故障时动作:停止均衡、修正SOC为上次值

  6. CATL协议的特殊支持 #if(1 == BMU_CATL_CAN_EN) CanSendUpCatlMsgCycleTask(); // 5ms周期发CATL心跳 #endif - 编译期配置支持多客户协议

  7. CANopen/J1939的对比分析(延伸) - 本工程使用自定义协议 vs 标准协议的权衡 - J1939在商用车BMS的应用


专题十三:Modbus RTU协议实现

博客标题建议:《BMS Modbus RTU实现:从帧结构到寄存器映射的完整工程》

提纲要点:

  1. Modbus RTU帧结构 [地址1B][功能码1B][数据NB][CRC2B] 帧间隔:3.5字符时间(>1ms@9600bps)

  2. 功能码实现 - 0x03:读保持寄存器(读参数/状态) - 0x06:写单寄存器(写参数) - 0x10:写多寄存器(批量写参数) - 错误响应:功能码+0x80,异常码

  3. 寄存器映射设计(BMS典型映射) - 0x0000-0x00FF:实时状态(电压/温度/电流/SOC) - 0x0100-0x01FF:告警状态位 - 0x0200-0x02FF:可写参数 - 0x1000-:历史记录读取

  4. UART DMA接收实现 - BSPUARTRcvTask:独立任务,循环等待DMA完成 - 帧超时判断:3.5字符时间无数据 → 帧结束 - CRC校验:多项式0xA001

  5. 主从模式 - 本工程同时支持:作为从站响应上位机,作为主站轮询下位设备


专题十四:电源管理与功能安全——FS6503 SBC

博客标题建议:《车规SBC FS6503:BMS电源管理与ASIL-D功能安全实现》

提纲要点:

  1. SBC(System Basis Chip)的作用 - 集成:LDO电源、CAN收发器、看门狗、安全状态机 - 为MCU提供受监控的供电和复位

  2. FS6503安全状态机 - INIT → NORMAL → STANDBY → SLEEP 状态转换 - MCU必须定期喂狗,否则触发复位 - 看门狗窗口模式:喂狗过早/过晚都会触发复位(防止死循环喂狗)

  3. FS65DiagnosticTask(5ms调用) - 定期读取FS65状态寄存器 - 检测:过压、欠压、过温、看门狗状态 - 喂狗序列:SPI发送特定序列

  4. 启动顺序中的FS65 BSPDriverInit(): 初始化FS6503 → 进入正常工作模式 期间喂狗避免复位

  5. 功能安全意义(ISO 26262/IEC 61508) - ASIL-D:汽车最高安全完整性等级 - SBC提供的硬件冗余:独立于MCU的看门狗 - 失效安全:MCU死机 → SBC触发安全状态 → 继电器断开


专题十五:参数管理与持久化存储

博客标题建议:《嵌入式参数管理:EEPROM+Flash的分层存储策略》

提纲要点:

  1. 存储介质分工 内部Flash(S32K146内置):程序代码 + 出厂默认参数 外部EEPROM(M24512):运行时参数(频繁读写,掉电保持) 外部Flash(SST26VF064):历史波形记录(大容量,顺序写)

  2. 参数分组体系(从文件名和变量名推断) - gGBmuGenPara_102[]:通用参数(电压限值/容量/SOC等,约200项) - gGBmuHigLevPara_103[]:高层级参数(从控数量/单体数等硬件配置) - gGHardPara_104[]:硬件参数(均衡时间/补偿系数等) - gGSysCapInfo_61[]:运行时信息(SOC/能量等,不持久化)

  3. EEPROM写保护策略 - 只在值变化时写(防止频繁写缩短寿命) - SOC写策略:变化≥0.1%才写 - M24512:写周期>5ms,必须有写完成等待

  4. ParaStoreCopyTask(10ms子任务) - 后台参数写任务,分散EEPROM写操作 - 避免在中断/关键路径中写EEPROM

  5. Flash历史记录 - RcdFaultWaveHandleTask(100ms):故障波形数据缓冲 - RcdStoreHandleTask(500ms):历史记录写入 - LoadAppFlashErasHandleAPI(300ms):后台擦除(SPI Flash必须先擦后写)

  6. 掉电数据一致性保证 - 关键参数写入后必须校验读回 - 多副本存储(写两份,读时校验CRC)


专题十六:嵌入式C语言工程化编码规范

博客标题建议:《工业BMS代码规范:从命名约定到防御性编程的工程实践》

提纲要点:

  1. 命名约定体系 g前缀:全局变量(gGBmuGenPara_102) s前缀:静态变量(sLTC6813CellVoltAD) e前缀:枚举值(eBmuGenPara102_NowSoc) API后缀:对外接口函数(GetGCellMaxVoltAPI) Hook后缀:用户实现的回调函数(EnerChangEepGNowSocHook) Task后缀:任务函数(CellInfoSampleTask)

  2. 类型定义 typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef signed char s8; typedef signed short s16; typedef signed int s32; - 显式位宽,避免平台差异 - 与stdint.h的对比

  3. 防御性编程实践 // 越界保护 if(num >= gGBmuHigLevPara_103[eBmuHigLevPara103_BsuVNum]) return; // 参数合法性 if(flag > 1) return; // 溢出防护 if(corrTemp > 167) corrTemp = 167; if(corrTemp < 0) corrTemp = 0;

  4. ABS宏的正确写法 #define ABS(a, b) ((a) > (b) ? ((a)-(b)) : ((b)-(a))) // 注意:与标准abs()不同,这是两数之差的绝对值

  5. 编译期配置(多项目支持) #if(1 == PRJ_PARA_NUM_INFO) // 宁温项目 #elif(2 == PRJ_PARA_NUM_INFO) // CATL 240Ah项目 #elif(5 == PRJ_PARA_NUM_INFO) // CATL液冷项目 #else // 默认 #endif - 通过宏实现同一份代码支持多个硬件配置

  6. 接口与实现分离 - XXXInterface.c:对外接口(Hook函数声明) - XXXUser.c:用户具体实现 - 意义:库代码与用户代码解耦,便于复用

  7. 静态分析友好的代码风格 - 所有函数返回值通过(void)显式忽略 - 避免全局变量直接访问(通过API函数) - (void)DEVGPIOSetPortState(...) 显式丢弃返回值


专题十七:电流采样与高压侧测量

博客标题建议:《BMS电流测量:霍尔传感器+分流器的双冗余方案》

提纲要点:

  1. 电流传感器类型 - 霍尔效应传感器:非接触,适合大电流,有零点漂移 - 分流器:接触式,精度高,有功耗 - 本工程:MCP3913 ADC采集分流器电压(推断)

  2. LTC2949精密库仑计 - 同时测量:电流、电压、温度、功率、能量积分 - 内置积分器:硬件级安时积分,精度高于软件积分 - SPI接口,独立于LTC6813

  3. 高压侧测量(DC bus电压) - 配置宏BMU_DC_VH_TYPE决定测量方式:

    • 类型1:LTC2949直接测量

    • 类型2:外部分压电阻+ADC

    • 类型3:从CAN读取

  4. 低压侧ADC(LowADCSamp) - MCU内部12/16位SAR ADC - 采集:辅助电源电压、温度传感器、绝缘检测

  5. 电流零漂校正 - 上电静置期间测量零点偏移 - 运行期间持续校正(基于空闲状态检测)


专题十八:继电器控制与预充电策略

博客标题建议:《BMS继电器控制:预充电保护与粘连检测的完整实现》

提纲要点:

  1. 主回路拓扑 电池+ → 主正继电器 → 负载 电池- → 主负继电器 → 负载 预充电路:主正旁路串预充电阻

  2. 上电预充序列

  3. 闭合主负继电器

  4. 闭合预充继电器(串联大电阻,限流)

  5. 等待负载电容充电(监测高压侧电压上升)

  6. 当高压 > 电池电压×90%时,闭合主正继电器 e. 断开预充继电器

  7. 粘连检测时序 - 吸合前检测:主正高压应接近0(若有电压→粘连) - 断开后检测:主正高压应跌落(若仍高→粘连)

  8. GroupSysIoUpDnCtrlTask(1000ms) - 系统级IO上下电管理 - 继电器状态机:OPEN→PRECHARGE→CLOSE→CHECK


专题十九:多项目工程管理(一码多项目)

博客标题建议:《嵌入式多项目管理:编译宏+Hook模式支持多客户硬件》

提纲要点:

  1. 问题背景 - 同一BMS平台服务多个客户:CATL、宁德、REPT等 - 电池参数不同、NTC型号不同、CAN协议不同 - 如何用一套代码维护?

  2. 编译宏分层 PRJ_PARA_NUM_INFO:项目编号(1/2/3/4/5) BMU_CATL_CAN_EN:是否启用CATL协议 BMU_DC_VH_TYPE:高压测量方式 MAX_LTC6813_NUM:最大从控数量

  3. 运行时参数化 - gGBmuHigLevPara_103[eBmuHigLevPara103_BsuNum]:从控数量从EEPROM读取 - 出厂配置:生产线写入对应项目参数

  4. Hook回调模式 - 库代码调用Hook函数(弱符号或接口文件) - 用户在XXXUser.c中实现具体行为 - 好处:库代码无需修改,仅替换User文件


博客写作路线图(推荐发布顺序)

入门系列(基础知识):

1. BMS系统架构总览

2. 锂电池基础:单体特性与成组

3. NTC温度采集

4. LTC6813电压采集

算法系列(核心价值):

5. 安时积分法完整实现

6. SOC多策略修正算法

7. SOC显示平滑算法

8. SOH双方法计算

9. 卡尔曼滤波理论与BMS应用(理论篇)

RTOS系列:

10. FreeRTOS软件定时器+任务混合架构

11. 状态机设计:12状态采样任务剖析

通信系列:

12. CAN总线3路分工设计

13. Modbus RTU完整实现

工程化系列:

14. 嵌入式C编码规范

15. 多项目一码管理

16. 参数分层存储策略

安全系列:

17. 故障诊断状态机

18. FS6503功能安全与看门狗

19. 继电器控制与预充电

20. 被动均衡策略


以上共19个专题、1个路线图,覆盖了本BMS工程所有核心知识域。每个专题提纲均来自实际代码中提炼的工程细节,确保博客内容有代码支撑、有原理解释、有工程价值。

More from this blog

Integrated PV-Storage-Load Forecasting: Empowering EMS with Predictive Intelligence

光伏-储能-负荷联合预测:给 EMS 装上"预知能力" 本文结合我正在维护的一套工业储能管理系统的真实工程实践,聊聊如何把预测能力嵌入 EMS 决策链路。代码片段均来自项目实际文件,不是伪代码。 一、为什么 EMS 需要预测? 我在调试这套系统的 MQTT 指令链路时,发现一个有意思的现象:EMS 的充放电决策完全依赖当前时刻的 SOC 和预设的时段计划表。翻开 ems_management

Jun 8, 20264 min read

电力需求响应——SEMS/REMS层级架构下的多站协调控制

作者:储能系统固件开发工程师日期:2026-04-14项目背景:工商业储能管理系统(BESS),支持川崎项目多站联合需求响应,SEMS为站级本地EMS,REMS为上级远程EMS 一、为什么需要两级EMS? 最初,项目只有一个站级EMS(站级能量管理系统,SEMS)。SEMS负责控制本站的PCS充放电,执行时段计划、防逆流、防过载,运行得还算平稳。 然而,当客户在川崎项目提出"多个储能站联合响应

Apr 14, 20267 min read

BMS SOC显示平滑算法:让百分比变化符合用户直觉

作者:悦悦 | 平台:S32K146 + FreeRTOS | 源文件:SocDisplay.c 前言 在储能BMS系统里,SOC(State of Charge,荷电状态)是用户最直接感知的核心指标。从EMS大屏到HMI触摸屏,SOC百分比就是电池的"油表"。 然而,算法层计算出来的SOC是一个不断跳变的原始值。把它直接推给显示层,用户看到的将是一个毫无规律、时快时慢、甚至会"倒退"的数字—

Apr 11, 20267 min read

EMS储能工程师的职业发展分析

一、你现在真实的竞争力画像 先说实话,让你有清醒认知。 从你的工程代码来看,你具备的能力是: 你最大的护城河不是C语言,而是"懂储能业务的嵌入式工程师"这个组合。 这个组合的人,全中国不超过几千人。 二、五大问题的系统回答 问题1:深度 vs 全栈,如何提升不可替代性? 核心判断:你不应该二选一,而是走"T型 + 业务锚点"路线。 什么是你的T型结构? 具体要做什么? 向下打深(6个月内优

Apr 9, 20262 min read2

BMS

12 posts