CAN 总线在 BMS 中的应用详解


title: “CAN 总线在 BMS 中的应用详解”
date: “2026-08-28”
category: “通信与协议”
tags: [“CAN总线”, “通信协议”, “BMS技术”]
slug: “can-bus-bms-application”


引言

BMS 里有一类问题,不出事的时候没人注意,一旦出问题就是整车停摆级别的故障:通信

主控单元(BCU)要跟各个从控单元(BMU)要电压温度,后向整车控制器(VCU)、充电机、DCDC、TBOX 又要跟 BCU 要状态。这些链路里挑大梁的,在乘用车和商用车领域几乎清一色是 CAN 总线。

本文不谈 CAN 的教科书定义,只聊 BMS 工程师真正要抠的细节:内部 CAN 和外部 CAN 为什么分层、报文 ID 和信号矩阵怎么规划、仲裁与位定时这些容易被忽略的地雷,以及整车层级 BMS 要发哪些报文、怎么和 OBD II 及国标充电协议打交道。

一、为什么 BMS 内部和外部要分成两路 CAN

先纠正一个常见误区:不是”一辆车一条 CAN”就完事了。BMS 里通常至少两路独立 CAN,职责完全不同。

内部 CAN(BMU ↔ BCU,也叫采集链)。BCU 要实时拿到每个电池模组里几十上百个单体的电压和温度。这条链路的特点是:节点多、数据量大、刷新周期短(典型 100~200 ms)、对确定性和同步性要求高,而且不能和整车网络的负载搅在一起。

外部 CAN(BCU ↔ VCU / 充电机 / BMS 对外的网关)。这条链路对接的是整车网络,负载高、节点杂、优先级争抢激烈。如果内部采集数据也往这上面塞,高压状态报文很容易被动力总成的高频报文挤占延迟。

工程上还有一个更实际的理由:电气隔离。内部 CAN 靠近高压采样区,外部 CAN 跨到低压整车网络,两路之间用隔离收发器(如 ISO1050、TJA1051T 加隔离电源)隔开,防止高压侧故障或地电位差串扰到整车。

分层之后,BCU 就成了一个”翻译官”:内部收原始数据,做 SOC/SOH/SOP 估算和故障诊断,再把结果打包成整车约定的报文发到外部 CAN。

二、报文 ID 与信号矩阵:先立规矩再写代码

CAN 报文能不能跑通,一半功夫在前期信号矩阵(dbc 文件)设计,而不是在驱动代码。ID 分配和信号布局一旦定错,后面所有 ECU 都要跟着改,成本极高。

ID 规划的几条经验:

  1. 按优先级分 ID 高段。 CAN 的仲裁是 ID 越小优先级越高。BMS 的故障、断高压请求这类安全相关报文,必须拿低 ID(高优先级),让它们在总线繁忙时也能抢到发送权。
  2. 预留扩展帧空间。 现在整车节点越来越多,很多项目已经用 29 位扩展 ID。设计时别假设 11 位标准帧够用,留出扩展 ID 的迁移空间。
  3. 同源报文周期对齐。 电压、温度这类周期性数据,让它们在同一时间基准上发送,VCU 侧才好做超时判断和丢失检测。

信号布局(signal layout)同样讲究。一个 Lesson learned:尽量让一个信号不要跨字节对齐到非整数位置,尤其是高压侧用到的带符号电压、电流值。信号起始位、长度、字节序(Intel/Motorola)一旦写错,向量工具(CANoe、CANalyzer)里解析出来的值就是乱码。团队里应该定一条铁律:dbc 是唯一的通信契约,任何控制器改动先改 dbc,再改代码,禁止两边各自”脑补”。

下面是一段用 python-can 发一条标准 BMS 高压状态报文的示例,注意 DLC 和字节序的处理:

import can

# 以 11 位标准帧发送一条 BMS 高压状态报文
bus = can.interface.Bus(channel="can0", bustype="socketcan")

# 假设信号布局: 字节0 = 总电压高字节, 字节1 = 总电压低字节, 字节2 = 总电流高字节...
msg = can.Message(
    arbitration_id=0x180,      # 低 ID, 高优先级
    data=[0x02, 0x8A, 0x0F, 0xA0, 0x00, 0x00, 0x00, 0x00],
    is_extended_id=False,
)
bus.send(msg)

0x180 这个 ID 不是随手写的,它是 J1939 里 PGN 0xF004(电子发动机控制器)附近常见的高压系统报文起始 ID 区域,商用车里 BMS 的高压状态经常落在这一片。乘用车则更多按 OEM 私有协议排 ID。

三、位定时:最容易埋雷的参数

CAN 控制器配不好位定时,现象极其诡异:低速没事,高速一上数据量大一点就报总线错误,或者两条 ECU 之间时通时不通。根源在于采样点(sample point)和位时间各段的比例。

位时间由同步段(Sync Seg)、传播段(Prop Seg)、相位缓冲段 1(Phase Seg1)和相位缓冲段 2(Phase Seg2)组成。采样点位置大致是:

采样点 = (1 + PropSeg + PhaseSeg1) / 总 TQ 数

现场最常用的经验值:采样点放在 75%~87.5% 之间。放在 80% 附近是工业界默认的稳妥值。采样点太靠前(比如 60%),总线上的振铃还没衰减完就采样,容易误判;太靠后(比如 90%),对时钟容差和线缆延迟的容忍度就变差。

另一个关键参数是 SJW(同步跳转宽度)。它在节点间时钟有漂移时用于调整同步,一般取 1~2 个 TQ。SJW 设小了,长线缆、温差大的场景下相位偏移跟不上就会出错。

这些参数必须同一条总线上所有节点严格一致。改波特率(500 kbps → 250 kbps)时,不能只改波特率位数,PropSeg/PhaseSeg/SJW 都要跟着重算,否则换线缆长度或节点数量后随时可能翻车。

四、BMS 到底要往整车上发什么

站在 BCU 的角度,对外 CAN 的报文清单,直接决定整车能不能正确做高压上下电和能量管理。一股脑把内部几百个单体电压全发出去,既没必要也占带宽。典型的最小集合是这几类:

报文 关键信号 典型周期 方向
高压系统状态 总电压、总电流、SOC、SOH 100 ms BCU → VCU
最大/最小单体信息 max/min 电压、对应编号、温度 100 ms BCU → VCU
充放电能力 允许充电/放电功率(SOP) 100 ms BCU → VCU/充电机
绝缘状态 绝缘电阻值、告警位 500 ms BCU → VCU
故障与状态 故障等级、继电器/接触器状态 100/500 ms 双向
上下高压握手 预充、主正主负接触器请求与回执 事件触发 双向

其中 SOP(State of Power)报文是 BMS 最值钱的一条输出。VCU 拿到可充/可放功率上限后,才能决定驱动扭矩限制和回馈策略;充电机也靠它来调节充电电流。SOP 报文发错了、发慢了,轻则驾驶感受差,重则在低温下电池过放或过充。

上下高压握手是另一条性命攸关的链路。典型的握手流程是一条事件驱动的状态机:VCU 请求上高压 → BMS 检查绝缘、预充目标 → 闭合预充接触器 → 预充电压达标 → 闭合主接触器 → 回执”高压就绪”。这条链路里每一条报文都必须有超时和重发机制,通信中断时 BCU 必须能够自主安全下高压,而不是傻等 VCU 的指令。

五、和 OBD II、国标充电协议的对接

BMS 工程师绕不开两类协议对接,都和 CAN 相关,但性质完全不一样。

OBD II(诊断)。按 ISO 15765,诊断报文走的是 CAN 之上的 TP(传输层)协议,超过 8 字节的用多帧传输(首帧 FF + 流控帧 FC + 连续帧 CF)。读 DTC、读数据流标识符(PID)都要通过 0x7DF / 0x7E8 这类诊断 ID 走。BMS 要把单体电压、SOC 等映射成标准 PID 或 OEM 扩展 PID,供售后诊断仪读。

这里有个坑:诊断响应往往要求”当前值”,而 BMS 内部数据是周期刷新的。如果响应时直接回最早缓存的值,诊断仪上看到的数据会滞后。正确做法是诊断服务触发时先同步一次最新采集值再回。

国标充电(GB/T 27930)。直流快充时,BMS 和充电机之间就走 CAN,报文协议是国标规定死的,ID 从 0x1801F456(BMS 辨识报文)到充电机辨识、手车报文、充电参数、中止充电等一系列。BMS 端要严格按国标报文周期(充电参数 50 ms、BMS 状态 250 ms)发送,超时就要进入错误处理。

GB/T 27930 还有一个容易疏忽的细节:充电握手阶段的超时计时从首次收到充电机报文开始,BMS 侧必须对每个阶段做独立超时判断,任意一步超时都要能安全中止并上报,否则可能卡在中间态,接触器状态和充电机状态对不上。

六、可靠性:通信冗余与降级策略

CAN 是单线差分(CAN_H / CAN_L),好处是抗共模干扰强,坏处是一旦某段线束断路或某个节点把总线拉死,整条总线可能瘫痪。BMS 作为安全件,不能只靠单链路。

几条落地过的冗余措施:

  1. 双路 CAN 互备。 关键状态报文同时在主 CAN 和备用 CAN 上发,VCU 侧任一路收到即可。成本略增,但能挡住单点断线。
  2. 总线关闭(bus-off)恢复机制。 当节点错误计数达到 256 进入 bus-off 后,要按规范在连续 128 次 11 个隐性位后恢复。BMS 的恢复不能裸恢复,恢复前要重新初始化控制器、清缓存,避免带病上线。
  3. 看门狗 + 缺帧检测。 VCU 侧对 BMS 的关键报文做超时监测,BMS 侧对充电机、VCU 的报文同样监测。一旦超时,按缺省的安全值降级(比如 SOP 直接降到 0)或主动下高压。

降级策略的核心思想一句话:通信不可信时,往安全方向收缩,而不是假设对方一定还在线。

结语

CAN 在 BMS 里不是一个”配个驱动能收发就行”的模块,它串起了采集、估算、诊断、上下电、充电五条链路。真正决定系统稳不稳的,是那些前期设计:ID 和 dbc 契约、位定时采样点、SOP 报文的时效、握手状态机的超时、以及总线失效后的降级路径。

对 BMS 工程师来说,把通信链路当成和电芯、AFE 一样的第一等安全件来对待,而不是最后”接根线”的收尾工作,很多现场排障和无谓的返工都能省掉。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Navigation

About

Writing on the Wall is a newsletter for freelance writers seeking inspiration, advice, and support on their creative journey.