一、简介
- 协议的制定:
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的设备会丢弃接收到的扩展数据帧/扩展遥控帧(因为控制场的保留位不符合语法),但是不会报错。 - 消息优先级:
CAN总线上的每个设备都可以发起传输,当一个设备正发送消息时,总线上其它所有设备都能接收到消息。CAN协议并没有限制连接在CAN总线上设备的数量,标识符表示的是数据的含义,而不是消息要送达的设备,因此同一个设备可以发送具有不同标识符的消息。标识符的逻辑值越小优先级越高,且有消息优先级:标准数据帧>标准遥控帧>扩展数据帧>扩展遥控帧。 - 通信方式:
CAN协议采用NRZ方式进行编码,使用位填充的方式进行信号同步,通过广播的方式传递消息,仅支持半双工通信。CAN协议规定了两种总线值:逻辑“0”(对应“显性”位)和逻辑“1”(对应“隐性”位)。当两个CAN设备同时向同一根线上传输“显性”位和“隐性”位时,这根线上实际的状态应该是“显性”位,相当于执行了线与操作(wired-AND),总线空闲时逻辑值为“1”。若CAN设备在发送“隐性”位时却检测到总线值是“显性”位,则该设备自动退出发送(在可能发生抢占的时候),由此实现非破坏的仲裁机制。 - 物理层
CAN总线的硬件通常由双绞线组成(也可以是光缆),传输的是一对差分信号,一根线名为CAN-H(称为CAN高),一根线名为CAN-L(称为CAN低),电压差等于CAN-H上的电压减去CAN-L上的电压。逻辑值“0”用CAN-H为高电平、CAN-L为低电平表示,逻辑值“1”用CAN-H为低电平、CAN-L为高电平表示。 - CAN协议并没有规定CAN-H和CAN-L的高低电平具体是多少伏特,所以不同车厂、甚至同一辆车里不同CAN总线上的设备都是不能直接接在一起进行通信的(可以通过CAN网关进行通信),不过同一条CAN总线上的设备对于高低电平的定义一定是一样的。CAN协议同样没有规定位速率(bit rate),但连接在同一条总线上的设备必须使用相同的位速率。需要注意的是一条CAN总线需要能工作,还需要在总线最远端接的两个设备上各接一个终端电阻(连接CAN-H和CAN-L),这两个电阻的阻值通常都是120欧姆,如下图所示:
二、帧格式
- 根据标识符长度来分类的话,CAN帧有标准帧和扩展帧两种;根据用途来分类的话,CAN帧有数据帧、遥控帧、错误帧、过载帧四种:
帧类型 | 用途 | 差别 |
数据帧 | 向其它节点发送数据 | 扩展数据帧比标准数据帧多20位(1位SRR替代遥控请求位,1位IDE标识符扩展位,18位ID标识符,均在仲裁场内) |
遥控帧 | 请求其它节点发送指定标识符的数据帧 | 扩展遥控帧比标准遥控帧多20位(1位SRR替代遥控请求位,1位IDE标识符扩展位,18位ID标识符,均在仲裁场内) |
错误帧 | 通知其它节点自己检测到总线错误 | 标准错误帧与扩展错误帧相同,因为不含仲裁场 |
过载帧 | 通知其它节点自己尚未做好接收准备 | 标准过载帧与扩展过载帧相同,因为不含仲裁场 |
帧间空间 | 每两帧之间需要有帧间空间,错误帧和过载帧除外 | 标准帧与扩展帧的帧间空间相同,因为不含仲裁场 |
- 一个标准/扩展数据帧(Data Frame)由如下7个部分组成:
- 帧起始(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必须是“隐性”的,因此标准数据帧的优先级高于标准遥控帧。 - 扩展数据帧的仲裁场(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位必须是“隐性”的,因此扩展数据帧的优先级高于扩展遥控帧。
- 控制场(Control Field)由6位组成,包括2位用作以后扩展的保留位(reserved bits)和4位数据长度码(Data Length Code)。发送端必须将两个保留位设置为“显性”位,若收到2个保留位不全是“显性”位的帧应该丢弃,而不是报错。数据长度码的逻辑值由下面的表格确定(d代表“显性”位,r代表“隐性”位):
- 数据场(Data Field)由数据帧中被发送的数据组成。它可包括0至8个字节,每个字节包括8位,其中首先发送最高有效位(MSB)。
CRC场(CRC Filed)由15位的CRC序列和1位的CRC定界符组成。CRC序列由由帧起始、仲裁场、控制场、数据场(假若存在)组成的无填充位流计算得出。CRC定界符紧跟在CRC序列后,由一个“隐性”位组成。 - 应答场(ACK Field)由1位应答槽(ACK Slot)和1位应答定界符(ACK Delimiter)组成。发送端应该将应答槽置为“隐性”位,若接收端的CRC校验结果为成功,则接收端应该在此时将应答槽置为“显性”位,发送端检测到总线状态为“显性”状态时就知道至少有一个接收端成功接受了该帧数据。应答定界符是一个“隐性”位。
- 帧结尾(End Of Frame)由7个“隐性”位组成。
- 一个标准/扩展遥控帧(Remote Frame)由如下6个部分组成(比数据帧少了数据场,并且仲裁场中的RTR遥控发送请求位为“隐性”,控制场中DLC数据长度码为请求的数据长度,其它部分与数据帧一致):
- 一个标准/扩展错误帧(Error Frame)由如下2个部分组成(连接在CAN总线上的设备总是处于"错误主动"状态或"错误被动"状态或“总线关闭”状态中的一种,状态之间的跳转由发送错误计数值TEC和接收错误计数值REC这两个变量确定):
- 错误标志(Error Flag)分为主动错误标志(Active Error Flag)和被动错误标志(Passive Error Flag)两种,主动错误标志由6个“显性”位组成(由处于"错误主动"状态的设备检测到错误时发送),被动错误标志由6个“隐性”位组成(由处于"错误被动"状态的设备检测到错误时发送,总线状态可以被其它设备重写成“显性”位),发出被动错误标志的设备检测到总线上有6个相同的逻辑值时即视为被动错误标志发送完毕。因为总线上可能有多个设备产生的错误标志发生重叠(如位错误与填充错误的错误标志相重叠),所以总线上错误标志的实际长度为6到12位。本文第四节会专门讲CAN协议的错误处理。
错误定界符(Error Delimiter)由8个“隐性”位组成,检测到总线上有8个连续的“隐性”位即为定界符传输完毕。 - 一个标准/扩展过载帧(Overload Frame)由如下2个部分组成(接收端在数据帧或遥控帧结束后需要有延迟时,或帧间空间的间歇期间检测到”显性“位后,应立即发送过载帧):
- 过载标志(Overload Flag)由6个“显性”位组成,与主动错误标志相同,过载标志也可能出现重叠。
过载定界符(Overload Delimiter)由8个“隐性”位组成,检测到总线上有8个连续的“隐性”位即为定界符传输完毕。 - 一个标准/扩展帧间空间(Interframe Space)由如下2个或3个部分组成(紧跟在数据帧或遥控帧后,可被错误帧或过载帧覆盖或打断):
- 间歇(Intermission)由3个”隐性“位组成,间歇期间所有设备不允许发送数据帧或遥控帧,但可以发送错误帧或过载帧。
暂停发送(Suspend Transmission)由8个”隐性“位组成,处于”被动错误“状态的设备在发送完一个数据帧或遥控帧后,应在帧间空间内多发8个”隐性“位以暂停发送,给其它可能想发送消息设备以抢占总线的时间。
总线空闲(Bus Idle)由任意数量的“隐性”位组成,总线空闲期间任意设备都可以开始发送消息。
三、编码方式
- 数据帧和遥控帧的帧起始、仲裁场、控制场、数据场(如果有的话)、CRC序列,均通过位填充的方法编码,即发送端在检测到5个连续相同逻辑值的位时,会自动在位流里插入一个不同逻辑值的位(用于信号同步)。
- 数据帧和遥控帧的CRC定界符、应答场、帧结尾,以及错误帧、过载帧,均不进行位填充。
四、错误处理
- 错误的种类(多种错误可能同时发生):
错误的种类 | 错误的内容 | 备注 | 需要检错的帧(场) | 需要检错的设备 |
位错误 | 比较输出值和总线值(不含填充位),当两值不一样时所检测到的错误。 | 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没被传送过来时所检测到的错误)。 | 数据帧(应答槽)、遥控帧(应答槽) | 发送端 |
- 错误帧的发送时机(检测出满足错误条件的设备发送错误标志通报错误,发送端发送完错误帧后,将再次发送数据帧或遥控帧):
错误的种类 | 输出时序 |
位错误 填充错误 格式错误 ACK错误 | 从检测出错误后的下一位开始发送错误标志。 |
CRC错误 | 应答定界符后的下一位开始发送错误标志。 |
- CAN总线上的设备总处于以下三个状态中的一个:
"错误主动"状态 | "错误被动"状态 | “总线关闭”状态 |
"错误主动"状态说明该设备处于可以正常参加总线通信的状态 | "错误被动"状态说明该设备处于易发生错误的状态 | 处于“总线关闭”状态的设备不允许参加总线上的通信 |
处于"错误主动"状态的设备检测到错误时,发送主动错误标志(6个“显性”位) | 处于"错误被动"状态的设备虽能参加总线通信,但为不妨碍其它设备通信,接收时不能积极地发送错误通知 | 消息的接收和发送均被禁止 |
处于"错误被动"状态的设备即使检测到错误,而其它处于"错误主动"状态的设备如果没发现错误,整个总线也被认为是没有错误的 | ||
处于"错误被动"状态的设备检测出错误时,发送被动错误标志(6个“隐性”位) | ||
另外,处于"错误被动"状态的设备在发送结束后不能马上再次开始发送。在开始下次发送前,在帧间空间内必须插入“暂停发送”(8 个位的“隐性”位) |
- 发送错误计数值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 |
- 状态的跳转条件:
五、常见标准的对比