一、简介

  1. 协议的制定:
    CAN是Controller Area Network的缩写,译为控制器局域网,常称作CAN总线,多用于汽车电子和工业控制。CAN协议最早由博世公司提出,后被多个标准化组织进一步细化,本文将在最后一节列出这些标准之间的细微差别。目前CAN总线中使用最广泛的正是CAN 2.0 A/B协议,也称作传统CAN(Classic CAN)。其中CAN 2.0A协议仅支持标帧格式,而CAN 2.0B协议支持标准帧格式(Stand Frame,11位标识符)和扩展帧格式(Extend Frame,29位标识符),CAN 2.0B协议的存在只是为了解决标识符不够用的情况(标识符也称作CAN ID,位于数据帧或遥控帧的仲裁场),所以CAN 2.0B和CAN 2.0A一样每个数据帧最多传输8个字节的数据。标准帧和扩展帧可以在同一条CAN总线上传输。仅支持CAN 2.0A的设备会丢弃接收到的扩展数据帧/扩展遥控帧(因为控制场的保留位不符合语法),但是不会报错。
  2. 消息优先级:
    CAN总线上的每个设备都可以发起传输,当一个设备正发送消息时,总线上其它所有设备都能接收到消息。CAN协议并没有限制连接在CAN总线上设备的数量,标识符表示的是数据的含义,而不是消息要送达的设备,因此同一个设备可以发送具有不同标识符的消息。标识符的逻辑值越小优先级越高,且有消息优先级:标准数据帧>标准遥控帧>扩展数据帧>扩展遥控帧。
  3. 通信方式:
    CAN协议采用NRZ方式进行编码,使用位填充的方式进行信号同步,通过广播的方式传递消息,仅支持半双工通信。CAN协议规定了两种总线值:逻辑“0”(对应“显性”位)和逻辑“1”(对应“隐性”位)。当两个CAN设备同时向同一根线上传输“显性”位和“隐性”位时,这根线上实际的状态应该是“显性”位,相当于执行了线与操作(wired-AND),总线空闲时逻辑值为“1”。若CAN设备在发送“隐性”位时却检测到总线值是“显性”位,则该设备自动退出发送(在可能发生抢占的时候),由此实现非破坏的仲裁机制。
  4. 物理层
    CAN总线的硬件通常由双绞线组成(也可以是光缆),传输的是一对差分信号,一根线名为CAN-H(称为CAN高),一根线名为CAN-L(称为CAN低),电压差等于CAN-H上的电压减去CAN-L上的电压。逻辑值“0”用CAN-H为高电平、CAN-L为低电平表示,逻辑值“1”用CAN-H为低电平、CAN-L为高电平表示。
  5. Java ICMP 协议 java can协议_CAN

  6. CAN协议并没有规定CAN-H和CAN-L的高低电平具体是多少伏特,所以不同车厂、甚至同一辆车里不同CAN总线上的设备都是不能直接接在一起进行通信的(可以通过CAN网关进行通信),不过同一条CAN总线上的设备对于高低电平的定义一定是一样的。CAN协议同样没有规定位速率(bit rate),但连接在同一条总线上的设备必须使用相同的位速率。需要注意的是一条CAN总线需要能工作,还需要在总线最远端接的两个设备上各接一个终端电阻(连接CAN-H和CAN-L),这两个电阻的阻值通常都是120欧姆,如下图所示:
  7. Java ICMP 协议 java can协议_汽车电子_02

二、帧格式

  1. 根据标识符长度来分类的话,CAN帧有标准帧和扩展帧两种;根据用途来分类的话,CAN帧有数据帧、遥控帧、错误帧、过载帧四种:

帧类型

用途

差别

数据帧

向其它节点发送数据

扩展数据帧比标准数据帧多20位(1位SRR替代遥控请求位,1位IDE标识符扩展位,18位ID标识符,均在仲裁场内)

遥控帧

请求其它节点发送指定标识符的数据帧

扩展遥控帧比标准遥控帧多20位(1位SRR替代遥控请求位,1位IDE标识符扩展位,18位ID标识符,均在仲裁场内)

错误帧

通知其它节点自己检测到总线错误

标准错误帧与扩展错误帧相同,因为不含仲裁场

过载帧

通知其它节点自己尚未做好接收准备

标准过载帧与扩展过载帧相同,因为不含仲裁场

帧间空间

每两帧之间需要有帧间空间,错误帧和过载帧除外

标准帧与扩展帧的帧间空间相同,因为不含仲裁场

  1. 一个标准/扩展数据帧(Data Frame)由如下7个部分组成:
  2. Java ICMP 协议 java can协议_数据帧_03

  3. 帧起始(Start Of Frame)代表着一个数据帧或遥控帧开始传输,CAN设备只能在总线空闲的时候才能发起传输,它仅由一个“显性”位构成,CAN总线上的所有设备在该“显性”位的前沿会进行信号同步。
    标准数据帧仲裁场(Arbitration Field)由11位的标识符(ID,identifier)和1个遥控发送请求位(RTR-BIT,Remote Transmission Request BIT)组成。标识符的长度为11位,这些位以ID-10至ID-0的顺序发送(在支持CAN 2.0 B的设备中为ID-28至ID-18),最低位为ID-0(在支持CAN 2.0 B的设备中为ID-18),其中高7位(ID-10到ID-4)不能全为“隐性”位(在支持CAN 2.0 B的设备中为ID-28至ID-22),因此标识符的逻辑值越小优先级越高(逻辑值“0”代表“显性”位),在支持CAN 2.0 B的设备中标准帧里不存在的标识符低18位ID-17至ID-0可视为充零。遥控发送请求位RTR在数据帧中,必须是“显性”的,而在遥控帧中,遥控发送请求位RTR必须是“隐性”的,因此标准数据帧的优先级高于标准遥控帧。
  4. Java ICMP 协议 java can协议_Java ICMP 协议_04

  5. 扩展数据帧仲裁场(Arbitration Field)由11位的基本标识符(Base ID)、1位的替代遥控请求位(SRR,Substitute Remote Request BIT)、1位的标识符扩展位(IDE,Identifier Extension Bit)、18位的扩展标识符(Extend ID)、遥控发送请求位(RTR-BIT,Remote Transmission Request BIT)组成。基本标识符的长度为11位,这些位以ID-28至ID-18的顺序发送,最低位为ID-18,其中高7位(ID-28到ID-22)不能全为“隐性”位。替代遥控请求位SRR是一个“隐性”位,对应于标准数据帧仲裁场中“显性”的遥控发送请求位RTR的位置,因此标准数据帧的优先级高于扩展数据帧。标识符扩展位IDE也是一个“隐性”位,对应于标准数据帧/遥控帧控制场第1个保留位r1这个“显性”位,因此标准遥控帧的优先级高于扩展数据帧,仅支持CAN 2.0 A的接收端检测到保留位r1是“隐性”位时会丢弃该帧,而支持CAN 2.0 B的接收端则会根据此位将该帧识别为扩展数据帧/遥控帧。扩展标识符包括18位,按ID-17到ID-0的顺序发送。遥控发送请求位在数据帧中,必须是“显性”的,而在遥控帧中,RTR位必须是“隐性”的,因此扩展数据帧的优先级高于扩展遥控帧。
  6. Java ICMP 协议 java can协议_标识符_05

  7. 控制场(Control Field)由6位组成,包括2位用作以后扩展的保留位(reserved bits)和4位数据长度码(Data Length Code)。发送端必须将两个保留位设置为“显性”位,若收到2个保留位不全是“显性”位的帧应该丢弃,而不是报错。数据长度码的逻辑值由下面的表格确定(d代表“显性”位,r代表“隐性”位):
  8. Java ICMP 协议 java can协议_标识符_06


  9. Java ICMP 协议 java can协议_CAN_07

  10. 数据场(Data Field)由数据帧中被发送的数据组成。它可包括0至8个字节,每个字节包括8位,其中首先发送最高有效位(MSB)。
    CRC场(CRC Filed)由15位的CRC序列和1位的CRC定界符组成。CRC序列由由帧起始、仲裁场、控制场、数据场(假若存在)组成的无填充位流计算得出。CRC定界符紧跟在CRC序列后,由一个“隐性”位组成。
  11. Java ICMP 协议 java can协议_数据帧_08

  12. 应答场(ACK Field)由1位应答槽(ACK Slot)和1位应答定界符(ACK Delimiter)组成。发送端应该将应答槽置为“隐性”位,若接收端的CRC校验结果为成功,则接收端应该在此时将应答槽置为“显性”位,发送端检测到总线状态为“显性”状态时就知道至少有一个接收端成功接受了该帧数据。应答定界符是一个“隐性”位。
  13. Java ICMP 协议 java can协议_数据帧_09

  14. 帧结尾(End Of Frame)由7个“隐性”位组成。
  15. 一个标准/扩展遥控帧(Remote Frame)由如下6个部分组成(比数据帧少了数据场,并且仲裁场中的RTR遥控发送请求位为“隐性”,控制场中DLC数据长度码为请求的数据长度,其它部分与数据帧一致):
  16. Java ICMP 协议 java can协议_标识符_10

  17. 一个标准/扩展错误帧(Error Frame)由如下2个部分组成(连接在CAN总线上的设备总是处于"错误主动"状态或"错误被动"状态或“总线关闭”状态中的一种,状态之间的跳转由发送错误计数值TEC和接收错误计数值REC这两个变量确定):
  18. Java ICMP 协议 java can协议_数据帧_11

  19. 错误标志(Error Flag)分为主动错误标志(Active Error Flag)和被动错误标志(Passive Error Flag)两种,主动错误标志由6个“显性”位组成(由处于"错误主动"状态的设备检测到错误时发送),被动错误标志由6个“隐性”位组成(由处于"错误被动"状态的设备检测到错误时发送,总线状态可以被其它设备重写成“显性”位),发出被动错误标志的设备检测到总线上有6个相同的逻辑值时即视为被动错误标志发送完毕。因为总线上可能有多个设备产生的错误标志发生重叠(如位错误与填充错误的错误标志相重叠),所以总线上错误标志的实际长度为6到12位。本文第四节会专门讲CAN协议的错误处理。
    错误定界符(Error Delimiter)由8个“隐性”位组成,检测到总线上有8个连续的“隐性”位即为定界符传输完毕。
  20. 一个标准/扩展过载帧(Overload Frame)由如下2个部分组成(接收端在数据帧或遥控帧结束后需要有延迟时,或帧间空间的间歇期间检测到”显性“位后,应立即发送过载帧):
  21. Java ICMP 协议 java can协议_数据帧_12

  22. 过载标志(Overload Flag)由6个“显性”位组成,与主动错误标志相同,过载标志也可能出现重叠。
    过载定界符(Overload Delimiter)由8个“隐性”位组成,检测到总线上有8个连续的“隐性”位即为定界符传输完毕。
  23. 一个标准/扩展帧间空间(Interframe Space)由如下2个或3个部分组成(紧跟在数据帧或遥控帧后,可被错误帧或过载帧覆盖或打断):
  24. Java ICMP 协议 java can协议_CAN_13

    Java ICMP 协议 java can协议_汽车电子_14

  25. 间歇(Intermission)由3个”隐性“位组成,间歇期间所有设备不允许发送数据帧或遥控帧,但可以发送错误帧或过载帧。
    暂停发送(Suspend Transmission)由8个”隐性“位组成,处于”被动错误“状态的设备在发送完一个数据帧或遥控帧后,应在帧间空间内多发8个”隐性“位以暂停发送,给其它可能想发送消息设备以抢占总线的时间。
    总线空闲(Bus Idle)由任意数量的“隐性”位组成,总线空闲期间任意设备都可以开始发送消息。

三、编码方式

  1. 数据帧和遥控帧的帧起始、仲裁场、控制场、数据场(如果有的话)、CRC序列,均通过位填充的方法编码,即发送端在检测到5个连续相同逻辑值的位时,会自动在位流里插入一个不同逻辑值的位(用于信号同步)。
  2. 数据帧和遥控帧的CRC定界符、应答场、帧结尾,以及错误帧、过载帧,均不进行位填充。

四、错误处理

  1. 错误的种类(多种错误可能同时发生):

错误的种类

错误的内容

备注

需要检错的帧(场)

需要检错的设备

位错误

比较输出值和总线值(不含填充位),当两值不一样时所检测到的错误。

1. 在仲裁场发送“隐性”位,但检测出“显性”位时,将被视为仲裁失利,而不是位错误。

2. 在仲裁场作为填充位发送“隐性”位时,但检测出“显性”位时,将不视为位错误,而是填充错误。

3. 发送端在应答槽发送“隐性”位,但检测到“显性”位时,将被判断为是其它设备的应答,而非位错误。

4. 发送被动错误标志(6个位隐性位)但检测出“显性”位时,将遵从错误标志的结束条件,等待检测出连续相同6个位的值(“显性”或“隐性”),并不视为位错误。

数据帧(SOF∼EOF)、遥控帧(SOF∼EOF)、错误帧、过载帧

发送端和接收端

填充错误

在需要位填充的场内,连续检测到6位相同的逻辑值时所检测到的错误。

数据帧(SOF∼CRC序列)、遥控帧(SOF∼CRC序列)

发送端和接收端

CRC错误

从接收到的数据计算出的CRC结果与接收到的CRC序列不同时所检测到的错误。

数据帧(CRC序列)、遥控帧(CRC序列)

接收端

格式错误

检测出与固定格式的位相反的格式时所检测到的错误。

1. 即使接收端检测出EOF(7个位的隐性位)的最后一位(第8个位)为显性电平,也不视为格式错误。

2. 即使接收端检测出数据长度码(DLC)中9∼15的值时,也不视为格式错误。

数据帧(CRC定界符、ACK定界符、EOF)、遥控帧(CRC定界符、ACK定界符、EOF)、错误定界符、过载定界符

接收端

ACK错误

发送端在应答槽(ACK Slot)中检测出“隐性”位时所检测到的错误(ACK没被传送过来时所检测到的错误)。

数据帧(应答槽)、遥控帧(应答槽)

发送端

  1. 错误帧的发送时机(检测出满足错误条件的设备发送错误标志通报错误,发送端发送完错误帧后,将再次发送数据帧或遥控帧):

错误的种类

输出时序

位错误

填充错误

格式错误

ACK错误

从检测出错误后的下一位开始发送错误标志。

CRC错误

应答定界符后的下一位开始发送错误标志。

  1. CAN总线上的设备总处于以下三个状态中的一个:

"错误主动"状态

"错误被动"状态

“总线关闭”状态

"错误主动"状态说明该设备处于可以正常参加总线通信的状态

"错误被动"状态说明该设备处于易发生错误的状态

处于“总线关闭”状态的设备不允许参加总线上的通信

处于"错误主动"状态的设备检测到错误时,发送主动错误标志(6个“显性”位)

处于"错误被动"状态的设备虽能参加总线通信,但为不妨碍其它设备通信,接收时不能积极地发送错误通知

消息的接收和发送均被禁止

处于"错误被动"状态的设备即使检测到错误,而其它处于"错误主动"状态的设备如果没发现错误,整个总线也被认为是没有错误的

处于"错误被动"状态的设备检测出错误时,发送被动错误标志(6个“隐性”位)

另外,处于"错误被动"状态的设备在发送结束后不能马上再次开始发送。在开始下次发送前,在帧间空间内必须插入“暂停发送”(8 个位的“隐性”位)

  1. 发送错误计数值TEC和接收错误计数值REC的变动条件如下表所示(一次数据的接收和发送可能同时满足多个条件,多个错误标志即便发生重叠也需要分别计算):

接受和发送错误计数值的变动条件

发送错误计数值(TEC)

接收错误计数值(REC)

1

接收端检测出错误时。例外:接收端在发送错误标志或过载标志中检测出“位错误”时,接收错误计数值不增加。

——

+1

2

接收端在发送完错误标志后检测到的第一个位为"显性"位时。

——

+8

3

发送端在输出错误标志时。

+8

——

4

发送端在发送主动错误标志或过载标志时,检测出位错误。

+8

——

5

接收端在发送主动错误标志或过载标志时,检测出位错误。

——

+8

6

各设备从主动错误标志、过载标志的最开始检测出连续14个位的“显性”位时。之后,每检测出连续的8个位的“显性”位时。

发送时+8

接收时+8

7

检测出在被动错误标志后追加的连续8个位的“显性”位时。

发送时+8

接收时+8

8

发送端正常发送数据结束时(返回ACK且到帧结束也未检测出错误时)。

TEC>0时-1

——

9

接收端正常接收数据结束时(到CRC未检测出错误且正常返回ACK时)。

——

1≤REC≤127时-1,REC=0时不变,REC>127时设置REC=127

10

处于“总线关闭”状态的设备,检测到128次连续11个位的“隐性”位。

TEC=0

REC=0

  1. 状态的跳转条件:
  2. Java ICMP 协议 java can协议_标识符_15

五、常见标准的对比

Java ICMP 协议 java can协议_标识符_16


Java ICMP 协议 java can协议_CAN_17