第2章:CAN总线基础回顾——CAN 2.0与CAN FD的区别

各位同学,咱们今天聊聊CAN总线的基础。说实话,很多工程师干了三五年,对CAN的理解还停留在“能发数据就行”的层面。但你要是想真正吃透通信矩阵和DBC解析,这些基础必须得掰开了揉碎了讲。

我个人习惯,讲技术之前先问一个问题:为什么要有CAN FD? 你想想看,CAN 2.0都用了三十多年了,全球几十亿个节点跑得好好的,干嘛要折腾一个新版本?

嗯,答案其实很简单——不够用了。我在2018年做过一个ADAS项目,那时候摄像头和雷达的数据量已经让传统CAN总线喘不过气了。一条报文最多8个字节,你想想看,一个高清摄像头一帧图像几兆字节,用CAN传?那得等到猴年马月去。

2.1 CAN 2.0与CAN FD的核心差异

咱们先看一张对比表,一目了然:

特性 CAN 2.0(经典CAN) CAN FD(灵活数据速率)
最大数据长度 8字节 64字节
传输速率(数据段) 最高1 Mbps(通常500 kbps) 最高8 Mbps(数据段可切换高速)
帧格式 标准帧(11位ID)/ 扩展帧(29位ID) 兼容CAN 2.0,新增FD帧格式
CRC校验 15位 CRC 17位(≤16字节)/ 21位(>16字节)
位填充规则 固定填充 数据段可关闭填充(提高效率)
向后兼容 — 可与CAN 2.0节点共存于同一总线

说白了,CAN FD就是在CAN 2.0的骨架上做了两件事:提速和扩容。但要注意,这个“提速”不是全程都跑高速——它只在数据段切换高速,仲裁段还是老老实实跑原来的速率。为什么?因为仲裁机制决定了,所有节点必须用同一个速率来竞争总线。

核心要点: CAN FD的“灵活”体现在数据段可以动态切换速率,但仲裁段速率不变。这是为了保证与CAN 2.0节点的兼容性。

2.2 CAN报文结构深度拆解

不管CAN 2.0还是CAN FD,报文结构的核心骨架是一样的。我习惯把一条CAN报文比作一封信:ID是收件人地址,DLC是信件厚度,Data是信的内容。

2.2.1 ID(标识符)

ID的作用是标识报文的优先级和内容类型。11位ID的范围是0x000~0x7FF,29位扩展ID的范围是0x00000000~0x1FFFFFFF。数值越小,优先级越高。

我在项目中遇到过一个问题:两个ECU同时发送ID=0x100和ID=0x200的报文,结果ID=0x100的报文总是先发出去。当时有个新同事问我:“为什么不是ID大的先发?” 我说你想想看,仲裁的时候,显性位(0)会覆盖隐性位(1)。ID越小,高位上的0越多,自然就越容易抢到总线。

避坑指南: 我曾经在定义DBC时,把两个信号分配到了同一个ID的不同字节位置,结果忘了检查字节序(Intel/Motorola)。后来在台架上跑了一整天,数据全是乱的。嗯,从那以后我每次建DBC都会先画一张字节布局图。

2.2.2 DLC(数据长度码)

DLC告诉接收方这条报文里有多少个有效数据字节。CAN 2.0的DLC范围是0~8,对应0~8字节。CAN FD的DLC编码方式略有不同,它用4位二进制表示,但映射关系不是线性的:

DLC值(二进制) CAN 2.0数据长度(字节) CAN FD数据长度(字节)
0000~1000 0~8 0~8
1001 8 12
1010 8 16
1011 8 20
1100 8 24
1101 8 32
1110 8 48
1111 8 64

你看,CAN FD的DLC值从9到15,对应的数据长度是跳跃式增长的。为什么这么设计?说白了是为了兼容CAN 2.0的DLC编码规则,同时又能支持更大的数据负载。

2.2.3 Data(数据场)

数据场就是实际要传输的信号。CAN 2.0最多8个字节,CAN FD最多64个字节。但要注意,DBC解析时,我们关心的是信号在数据场中的起始位、长度、字节序、符号类型。这些信息都定义在DBC文件的信号描述里。

举个例子,一条报文ID=0x123,DLC=8,数据场是 01 02 03 04 05 06 07 08。如果DBC里定义了一个信号“EngineSpeed”,起始位在第3字节的第2位,长度12位,Intel格式,那么解析出来的值就是 0x0304 的低12位,再乘以缩放因子加上偏移量,得到实际的转速值。

注意: 很多初学者搞不清Intel和Motorola的字节序。我教你一个笨办法:Intel格式下,信号的起始位在低字节的低位,高位向高字节延伸;Motorola格式下,起始位在高字节的高位,低位向低字节延伸。画一张位图,比背十遍定义都管用。

2.3 位时序与仲裁机制

这部分是CAN总线的灵魂。你想想看,为什么CAN总线不需要像以太网那样用交换机?为什么所有节点可以同时往总线上发数据而不冲突?答案就在位时序和仲裁机制里。

2.3.1 位时序

CAN总线上每一位的传输时间由四个段组成:

  • 同步段(Sync_Seg):1个时间量子(Tq),用于同步所有节点
  • 传播段(Prop_Seg):1~8个Tq,补偿物理延迟
  • 相位缓冲段1(Phase_Seg1):1~8个Tq,用于采样点调整
  • 相位缓冲段2(Phase_Seg2):1~8个Tq,用于采样点调整

采样点通常位于Phase_Seg1和Phase_Seg2之间。我建议你把采样点设置在85%~90%的位置。为什么?因为总线上的信号有上升沿和下降沿的畸变,采样点太靠前容易采到毛刺,太靠后又可能错过有效电平。

我曾经在一个项目中,总线长度超过40米,节点数12个,波特率500 kbps。一开始采样点设在75%,结果时不时出现错误帧。后来我把采样点调到87.5%,问题就消失了。嗯,这就是经验。

2.3.2 仲裁机制

CAN总线的仲裁机制,说白了就是“谁先发0,谁就赢”。所有节点同时发送ID位,如果某个节点发送的是隐性位(1),但总线上检测到显性位(0),它就立刻退出竞争,转为接收状态。

这个过程是无损的——赢得仲裁的节点继续发送,输掉的节点自动重试。不会像以太网那样发生碰撞导致数据损坏。

我画了一张仲裁过程的流程图,帮你理解:

CAN总线仲裁机制流程图 节点A:ID=0x100 节点B:ID=0x200 节点C:ID=0x180 仲裁过程:逐位比较ID 显性位(0)覆盖隐性位(1) 仲裁结果:节点A获胜(ID最小) 节点A继续发送数据 节点B、C转为接收 注:ID值越小,优先级越高,仲裁获胜

你看,节点A的ID=0x100,二进制是 0001 0000 0000;节点B的ID=0x200,二进制是 0010 0000 0000。在最高位比较时,A发0,B发0,平手;第二位,A发0,B发1,A的显性位覆盖了B的隐性位,B立刻退出。节点C同理。

个人经验: 我建议你在设计网络时,把实时性要求高的报文(比如刹车、转向)分配较小的ID,把诊断和配置类报文分配较大的ID。这样能保证关键信号优先通过仲裁。

2.4 总结一下

这一章我们聊了三个核心点:

  • CAN 2.0 vs CAN FD:FD在数据段提速扩容,但仲裁段保持兼容
  • 报文结构:ID决定优先级,DLC决定长度,Data承载信号
  • 位时序与仲裁:采样点设置是关键,仲裁机制保证无损竞争

这些内容看起来基础,但我在实际项目中见过太多因为采样点设置不对、ID分配不合理导致的通信故障。嗯,基础不牢,地动山摇。下一章咱们就要开始动手解析DBC文件了,到时候你会感谢今天认真看了这些基础内容。

一句话记住: CAN总线的核心魅力在于——用最简单的物理层机制,实现了最优雅的分布式通信。


可可精品资料库