Skip to content

3.1 CAN 通信

何为 CAN 总线

多电控单元间交换数据使用的多主机局部网络串行通信协议

总的来说,就是一条通信线路上连接多个节点,各个节点都通过这条线路来发送信息,当一个节点发送消息时,其他节点监听;当多个节点发送消息是,按照优先级发送。

可实现 点对点,点对多点,全局广播的功能。

{

通信基础知识 - 链路

  • 地址
  • 冲突检测与避免
  • 误码校验
  • 滤波器与掩码(此部分内容摘抄自中科大 RM 系列教程之 CAN 通信)
    • 用于配置接收设备,注意,是过滤通过,而非过滤排除机制。即符合条件的报文会接收
    • 滤波器用于过滤出想要接收的信息,掩码 Mask 用于匹配想要接收的信息 ID
    • 如何过滤与匹配?以 CAN ID 作为匹配规则。标准格式中的 CAN ID 长度为 11b,也就是 CAN ID 最大为 0x7ff
      • 一个 CAN ID 为 0x114,如果我要配置一个滤波器只接收这个 CAN ID 的帧的话,就需要配置滤波器过滤目标为 0x114,掩码为 0x7ff。流程就是把掩码变成二进制 01 串,为 1 的位要与过滤目标一致
      • 一段 CAN_ID 为 0x114~0x117,如果我要配置一个滤波器只接收这一段 CAN ID 的帧的话,就需要配置滤波器过滤目标为 0x114,掩码为 0x7fc。也就是把掩码变成二进制 01 串,为 1 的位要与过滤目标一致

数据格式

帧类型

数据帧

数据帧包含以下部分

  • 帧起始(SOF单个显性位组成,总线空闲时,发送节点发送帧起始。其他节点同步于该帧起始位

  • 仲裁域:决定发送优先级

    • ID:顾名思义,所发送数据的身份标识,大小为 11 字节。
    • SRR:替代远程帧请求位,为显性
    • IDE:识别符扩展位,在整个数据格式中处于第 14 位。在标准帧格式中位于控制域,为显性;在扩展帧格式中位于仲裁域,为隐性
    • RTR:远程帧发送标识位,为显性
  • 控制域

    • IDE:已在仲裁域中解释过,不再赘述
    • r0, r1:保留位 0 和 1,在目前的 CAN 总线规范中没有明确定义用途。一般用于隐性电平填充。
    • DLC:数据段长度码;BCD 编码,范围 0~8
  • 数据域:MSB 优先传输

  • CRC 域:数据检错,CRC 校验值存放于 CRC 段

  • 应答域(ACK帧起始到 CRC 段之间的内容没有错误,则在 ACK 段发送显性电平

    • ACK 槽:发送节点发送隐性电平;接收正确的节点发送显性电平 → 总线与结果为显性电平。发送节点据此可判断发送成功
    • ACK 界定符:1 个隐性电平
  • 帧结尾(EOF7 个连续隐性位组成

相信上述内容有许多专有名词难以理解,这些内容将在文末进行阐释。

标准帧格式 如下

帧起始仲裁域控制域数据域CRC域ACK域帧结束
组成部分SOFID[0:10]RTRIDEr0DLCData:Byte0~Byte7CRC_Value[0:14]CRC界定符ACK槽ACK界定符EOF
数据大小/bit11111140~64151117

扩展帧格式标准帧格式 有如下区别

...仲裁域控制域...
组成部分...ID[0:10]SRRIDEID[11,28]RTRr1r0DLC...
数据大小/bit...1111181114...

远程帧

与数据帧相比,远程帧无数据域,由 6 个部分组成,也有标准格式和扩展格式,且 RTR 为 1(隐性电平

标准帧格式 如下

帧起始仲裁域控制域CRC域ACK域帧结束
组成部分SOFID[0:10]RTRIDEr0DLCCRC_Value[0:14]CRC界定符ACK槽ACK界定符EOF
数据大小/bit1111114151117

扩展帧格式标准帧格式 有如下区别

...仲裁域控制域...
组成部分...ID[0:10]SRRIDEID[11,28]RTRr1r0DLC...
数据大小/bit...1111181114...
#### 数据帧与远程帧的区别
比较内容数据帧远程帧
ID发送节点的 ID被请求发送节点的 ID
SRR0(显性电平)1(隐性电平)
RTR0(显性电平)1(隐性电平)
DLC发送数据长度请求的数据长度
有无数据段
CRC 校验范围帧起始 + 仲裁域 + 控制域 + 数据域帧起始 + 仲裁域 + 控制域

错误帧

CAN-bus 错误类型

  • CRC 错误:发送节点计算得到的 CRC 值与接收到的 CRC 值不匹配
  • 格式错误:传输的数据帧格式与任何一种合法帧格式不符
  • 应答错误:发送节点在 ACK 阶段没有接收到应答信号
  • 位发送错误:发送节点在发送时发现总线电平与发送电平不相同
  • 位填充错误:传输信号违反 “位填充” 规则

当出现以上 5 种错误类型之一时,发送或接收节点将发送错误帧,结构为 错误标识 + 错误界定符

主动错误标识:由处于主动错误状态的节点发送 ↓

6个连续显性电平位8个连续隐性电平位
00000011111111

被动错误标识:由处于被动错误状态的节点发送 ↓

6个连续隐性电平位8个连续隐性电平位
11111111111111

为防止无法正常接收的节点一直发送错误帧干扰通信,CAN-bus 规定了节点的三种状态及行为

  • REC:接收错误计数器

  • TEC:发送错误计数器

复位时二者都被清零

过载帧

当某接收节点没有做好接受下一帧数据准备时,将发送过载帧来通知发送节点

过载帧结构 过载标志 + 过载帧界定符

6个连续显性电平位(过载标志)8个连续隐性电平位(过载帧界定符)
00000011111111

由于存在多个节点同时过载且过载帧发送有时间差,可能出现叠加超 6 个位的情况

帧间隔

用于将数据帧或远程帧和他们之前的帧分开,但过载帧和错误帧前不会插入帧间隔

...其他帧帧间隔数据帧或远程帧...其他帧数据帧或远程帧...
- 帧间隔过后,若无节点发送帧则总线进入空闲
...帧间隔0~∞...
  • 帧间隔过后,如果被动错误节点要发送帧,则先发送 8 个隐性电平的传输延迟,再发送帧
...帧间隔传输延迟(8个隐性位)被动错误节点发送帧...

WARNING

保证主动错误节点优先发送,避免被动错误节点因硬件故障干扰整个网络

收发模式

  • 常规模式

    • 向总线发送

    • 从总线接收

  • 回环模式

    • 向总线和本机发送

    • 不从总线接收仅从本机接收

  • 静默模式

    • 不向总线发送仅向本机发送

    • 从总线和本机接收

  • 回环静默模式

    • 不向总线发送

    • 不从总线接收

    • 自收自发

一些疑惑及解答

何为显性电平?何为隐性电平?

** 答:** 显性电平在逻辑层面表现为 0,隐性电平在逻辑层面表现为 1;显性电平覆盖隐性电平;均为隐性电平时总线上才为隐性电平。CAN 采用差分电压发送电平(VdiffV_diff = CAN_H - CAN_L

CAN 总线为 “隐性逻辑 1)时,CAN_H 和 CAN_L 的电平为 2.5V(电位差 V_diff 为 0V)

为什么要有 120Ω 的电阻?

CAN_H 与 CAN_L 通过 120Ohm 电阻连接在一起,防止总线上传输的高频信号存在反射振铃效应导致信号不稳定、寄生电容导致信号响应速度变慢等情况

图解

下面一条为 CAN_Low,上面一条为 CAN_High

CAN 通信采用双绞线传输的优点?

答: 使外部干扰在两根导线上产生的噪声相同,以便后续的差分电路提取出有用信号

仲裁域如何实现仲裁功能?

答: CAN 控制器在发送数据的同时监测数据线的电平是否与发送数据对应电平相同,如果不同则停止发送并做其他处理 ↓

  1. 如果该位处于仲裁域,则退出总线竞争
  2. 如果处于其他域,则产生错误时间(ACK 或被动错误标志传输期间除外)

简而言之,显性电平覆盖隐性电平。同一位电平不相同时,显性电平继续发送,隐性电平的进入只听模式

数据帧与遥控帧的优先级

答: 数据帧优先级 > 遥控帧优先级,因为数据帧仲裁段 RTR 为显性

标准格式与扩展格式的优先级

** 答: ** 标准格式优先级 > 扩展格式优先级,因为标准格式 IDE 位为显性电平,扩展格式 IDE 位为隐性电平。

WARNING

对于前 11 位 ID 相同的标准格式和扩展格式才适用于此规则,前 11 位 ID 不相同的适用于仲裁规则

r0, r1 作用?什么是隐性电平填充?

答: r0 与 r1 为保留位,在当前的 CAN 标准中,这些位的具体用途并未明确定义。之所以用于隐性电平填充是因为 数字越大优先级越小,若为 1(即隐性电平)则永远不会用得到它。

BCD 编码?

** 答: **BCD 码(Binary-Coded Decimal用 4 位二进制数来表示 1 位十进制中的 0~9 这 10 个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。

十进制BCD 表达格式
00000
10001
20010
30011
40100
50101
60110
70111
81000
91001

此处仅列出上文中所需要的知识,具体请查阅参考资料 [4]

什么是 MSB 数据?

** 答: ** 最高有效位,二进制中代表最高值的比特位,这一位对数值的影响最大。

以数字 9 为例子,其二进制为 1001,若 MSB 发生错误,即最高位 1 变为 0,则整个数字变为了 1,误差为 8。

此处仅列出上文中所需要的知识,具体请查阅参考资料

CRC 如何计算?

答: CRC 全称为 循环冗余校验。其根本思想是在要发送的帧后面附加一个数,作为数据校验码,并生成一个新帧发给接收端,用于验证数据是否损坏。

从数学上讲,CRC 是数据的模二多项式 (polynomial) 除法的余数。因此,CRC 可以写成 CRC = data % 2 polynomial

计算过程

  1. 选定 CRC 生成多项式 G (x) 作为除数。G (x) 决定了校验码的生成方式,常用的 CRC 多项式包括 CRC-16(即除数共 17 位CRC-32。注意,G (x) 的最高位和最低位必须为 1。 以 4 位 CRC(二进制共 5 位)作为示例 11001 表示的就是 G(x)=x4+x3+1

    WARNING

    由于选择不同的多项式将导致相同数据产生不同的 CRC,所以发送方和接收方需要使用共同的多项式。 对于 CRC 来说,根据具体的使用场景,有些多项式比其他多项式更适合使用。例如,某些多项式可能更容易检测出连续位错误或交替位错误。

  2. 看所选定的除数二进制位数(假设为 k 位然后在要发送的数据帧(假设为 m 位)后面加上 k-1 位 “0然后以这个加了 k-1 个 “0“的新帧(一共是 m+k-1 位)以 “模 2 除法” 方式除以上面这个除数,所得到的余数(也是二进制的比特串)就是该帧的 CRC 校验码,也称之为 FCS(帧校验序列

    WARNING

    余数的位数一定要是比除数位数只能少一位,哪怕前面位是 0,甚至是全为 0(附带好整除时)也都不能省略。

  3. 再把这个校验码附加在原数据帧(就是 m 位的帧,注意不是在后面形成的 m+k-1 位的帧)后面,构建一个新帧发送到接收端

  4. 最后在接收端再把这个新帧以 “模 2 除法” 方式除以前面选择的除数,如果没有余数,则表明该帧在传输过程中没出错,否则出现了差错。

什么是模 2 除法

模 2 减法

答: 模 2 运算是对二进制数逐位进行的运算,不存在进位或借位,每个位被视为独立的数其实就是 C 语言中的异或运算)

下表为模 2 减法的数据表,其公式为 bit1bit2=XOR

bit1bit2XOR
000
011
101
110

模 2 除法

模二除法的执行类似于算术除法,唯一的区别是我们使用模二减法 (XOR) 而不是算术减法来计算每一步的余数。

假设被除数为 100100,除数为 1101

  1. 计算除数长度为 L,在示例中为 4

  2. 在被除数后面加上 L-1 位,这里为 3(即 CRC 长度)

  3. 用二进制模 2 进行计算,得到的余数即为 CRC 结果:001

1111011101)10010000011011000110110101101111011010110000011001101001

关于 模 2 运算 的更多知识,请参阅参考资料

何为主动错误状态?何为被动错误状态?

答: 主动错误(Active Error)是指节点在发送数据帧时发现总线上存在错误,并且主动向其他节点通知该错误。主动错误通常是由于发送节点检测到仲裁场(Arbitration Field)或控制位(Control Field)上的错误而产生的。

被动错误(Passive Error)是指节点在接收数据帧时检测到总线上存在错误,但不会主动通知其他节点。被动错误通常是由于接收节点检测到数据位(Data Field)或 CRC(Cyclic Redundancy Check)校验错误而产生的。接收节点会将错误信息记录下来,但不会对其他节点进行任何主动干预。被动错误表示总线上存在一些问题,但并不影响其他节点的正常通信。

主动错误和过载帧格式一致,如何区分?

** 答: ** 过载帧与主动错误帧具有相同的格式。但是,过载帧只能在帧间间隔产生,因此可通过这种方式区分过载帧和错误帧(错误帧是在帧传输时发出的

CSMA/CD 协议

此部分内容较长,单开一节讲起

参考资料