3、CAN通信协议与DBC解析:CAN2.0与CANFD区别、DBC文件结构、信号矩阵与报文周期

好,咱们进入第三章。这一章可以说是VCU测试的“地基”。

你想想看,VCU跟其他控制器怎么聊天?靠的就是CAN总线。不懂CAN协议,看不懂DBC文件,那你做测试就是盲人摸象。我个人习惯,带新人第一件事,就是让他先把DBC文件啃透。

3.1 CAN2.0与CANFD:到底差在哪?

先说CAN2.0。这是经典款,从90年代用到现在,稳定得一批。它的数据场最多8个字节,波特率最高1Mbps。说实话,对于大部分传统车控信号——比如车速、转速、油门——8个字节完全够用。

但问题来了。现在车上的功能越来越多,OTA升级、自动驾驶、高精地图……这些动辄几十个字节的数据包,CAN2.0就扛不住了。于是CANFD(Flexible Data-rate)应运而生。

核心区别就两点:

  • 数据场长度: CAN2.0最多8字节,CANFD最多64字节。差了8倍。
  • 波特率: CAN2.0最高1Mbps,CANFD在数据段可以切换到最高8Mbps(实际常用2Mbps或5Mbps)。

我遇到过不少项目,工程师把CANFD当CAN2.0用,结果发现总线负载率还是高。为什么?因为没开“加速模式”。CANFD的仲裁段还是用原来的速率(比如500kbps),只有数据段才切到高速。这个细节很多人会忘。

避坑指南: 我曾经在测试一个ADAS项目时,发现CANFD报文总是丢帧。查了半天,原来是DBC里把CANFD的“BRS”位(波特率切换位)设成了0。说白了,就是没告诉控制器“我要加速”。结果它一直用低速跑64字节的数据,总线直接堵死。

特性 CAN2.0 CANFD
数据场长度 最多8字节 最多64字节
最大波特率 1 Mbps 8 Mbps(数据段)
兼容性 广泛 向下兼容CAN2.0
典型应用 传统动力、车身控制 ADAS、OTA、高带宽传感器

小提示: 如果你的VCU项目同时支持CAN2.0和CANFD,记得在测试用例里专门加一条“混合总线压力测试”。我见过有的控制器在CANFD报文和CAN2.0报文交替发送时,会出现仲裁失败。嗯,这跟硬件收发器的设计有关。

3.2 DBC文件结构:别被它吓到

DBC文件,说白了就是CAN总线的“翻译官”。它告诉测试工具:哪个ID对应什么信号,信号在哪个字节的哪个位,单位是什么,范围是多少。

我第一次打开DBC文件时,也是一脸懵。满屏的VECTOR___XXX、SG_、BO_……其实结构很简单,就三大部分:

  • 报文定义(BO_): 定义了一个CAN报文的ID、名称、长度。
  • 信号定义(SG_): 定义了这个报文里每个信号的名字、起始位、长度、字节序、类型、范围、单位。
  • 属性定义(BA_): 定义了一些额外信息,比如报文周期、发送节点、接收节点。

举个例子,一个典型的DBC片段长这样:

BO_ 100 VCU_Status: 8 VCU
 SG_ VehicleSpeed : 0|16@1+ (0.01,0) [0|300] "km/h" VCU
 SG_ MotorTorque : 16|12@1+ (1,-500) [-500|500] "Nm" VCU
 SG_ BatterySOC : 28|8@1+ (0.5,0) [0|100] "%" VCU

我来拆解一下:

  • BO_ 100 VCU_Status: 8 VCU —— 报文ID是0x64(100十进制),名字叫VCU_Status,长度8字节,发送节点是VCU。
  • SG_ VehicleSpeed : 0|16@1+ (0.01,0) [0|300] "km/h" —— 信号从第0位开始,占16位,Intel格式(@1+),系数0.01,偏移0,范围0-300 km/h。

重点: 这里的“0|16”指的是起始位和长度。很多新手搞不清起始位是从LSB还是MSB开始算。记住:Intel格式(@1+)起始位是LSB,Motorola格式(@0+)起始位是MSB。我建议你直接在CANoe里用Graphic Panel拖出来看,比手动算快得多。

3.3 信号矩阵:测试的“作战地图”

信号矩阵,说白了就是一张大表。它把DBC里所有信号整理成一行一行的,方便你查。我习惯在项目开始前,先让团队把信号矩阵整理出来,然后贴在墙上。

一个标准的信号矩阵应该包含:

  • 信号名称 —— 跟DBC里一致
  • 报文ID —— 十六进制
  • 物理范围 —— 比如0-300 km/h
  • 分辨率/偏移 —— 比如0.01, 0
  • 默认值/初始值 —— 上电后没收到报文时的值
  • 超时时间 —— 多久没收到算超时
  • 发送条件 —— 周期性还是事件触发

举个例子:

信号名称 报文ID 物理范围 分辨率 偏移 默认值 超时时间 发送条件
VehicleSpeed 0x64 0-300 km/h 0.01 0 0 100 ms 周期10ms
MotorTorque 0x64 -500-500 Nm 1 -500 0 100 ms 周期10ms
BatterySOC 0x64 0-100 % 0.5 0 50 500 ms 周期100ms

我的习惯: 我会在信号矩阵里额外加一列“测试关注点”。比如对于车速信号,我会标注“注意超时后的默认值是否为0,以及从有效值跳变到0时是否有滤波”。这些细节,DBC里不会写,但测试时必须测。

3.4 报文周期:别小看这个参数

报文周期,就是报文多久发一次。常见的周期有10ms、20ms、50ms、100ms、500ms、1000ms。你可能会问:周期有什么好讲的?

其实这里坑很多。

第一,周期抖动。 理论上10ms发一次,但实际测试时你会发现,有的控制器发出来的报文周期在9.8ms到10.2ms之间波动。如果抖动超过±5%,就可能触发接收方的超时判断。我遇到过因为周期抖动导致VCU误判为通信故障,直接切入了跛行模式。

第二,周期一致性。 同一个报文,不同控制器发的周期可能不一样。比如VCU发车速是10ms,但BMS发的电池SOC是100ms。如果你在测试时用同一个定时器去采样,就会漏掉数据。

第三,事件触发 vs 周期触发。 有些报文不是周期发的,而是事件触发。比如“碰撞信号”,平时不发,撞车了才发。这种报文在DBC里通常没有周期属性,但测试时你必须模拟这个事件,看VCU能不能在10ms内响应。

警告: 我曾经在测试一个VCU项目时,发现某个报文在DBC里标注的周期是100ms,但实际测试时发现它有时候200ms才来一次。查到最后,是供应商把发送条件设成了“变化时发送”,而不是周期发送。所以,永远不要完全相信DBC里的周期字段,一定要用CANoe或PCAN抓一下实际波形。

好了,这一章的内容就这些。CAN协议和DBC解析,是VCU测试的“内功”。内功练好了,后面测什么都有底气。下一章我们讲测试环境的搭建,包括HIL台架和CANoe的配置,到时候见。