最近在学习CAN通讯,花费好多时间搜索资料,网络上大多数资料都是泛泛而谈,或者只是将CAN标准的文字罗列出来,看起来不够直观。不过,也找到了一些写的很好的资料,我将这些资料中对CAN知识点描述比较好的部分汇总起来并在某些地方添加一些例子,方便大家阅读,省去大家搜索查找各种文献的时间,提高效率。
1.什么是CAN
CAN 是Controller Area Network 的缩写(以下称为CAN),是ISO 国际标准化的串行通信协议。它是由研发和生产汽车电子产品著称的德国BOSCH公司开发的,并最终成为国际标准(ISO11898-1/ISO11519-2),是国际上应用最广泛的现场总线之一[1]。
CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN为底层协议专为大型货车和重工机械车辆设计的J1939协议。由于它具有的高可靠性和良好的错误检测能力而受到重视,被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射强及振动大的工业环境[1]。
在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个LAN,进行大量数据的高速通信”的需要,1986 年德国电气商博世公司开发出面向汽车的CAN 通信协议。此后,CAN 通过ISO11898 及ISO11519 进行了标准化,现在在欧洲已是汽车网络的标准协议[2]。
现在,CAN 的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面[2]。图 1 是车载网络的构想示意图。该车型有4个CAN网络构成,分别是传动CAN网段、混动CAN网段、车身CAN网段、和底盘CAN网段。
图1车载网络示意图
2. CAN网络协议
2.1 CAN协议与OSI模型
国际标准化组织ISO提出了一套网络体系结构模型,称为开放系统互联参考模型(Open Systems Interconnection,简称OSI),CAN协议也是基于该模型打造出来的。首先,来回顾一下ISO的OSI模型,见表1。
表1 OSI模型
ISO/OSI 基本参照模型 | 各层定义的主要项目 | |
软件控制 | 7 层:应用层 | 由实际应用程序提供可利用的服务。 |
6 层:表示层 | 进行数据表现形式的转换。 如:文字设定、数据压缩、加密等的控制 | |
5 层:会话层 | 为建立会话式的通信,控制数据正确地接收和发送。 | |
4 层:传输层 | 控制数据传输的顺序、传送错误的恢复等,保证通信的品质。如:错误修正、再传输控制。 | |
3 层:网络层 | 进行数据传送的路由选择或中继。 如:单元间的数据交换、地址管理。 | |
硬件控制 | 2 层:数据链路层 | 将物理层收到的信号(位序列)组成有意义的数据,提供传输错误控制等数据传输控制流程。 如:访问的方法、数据的形式。 通信方式、连接控制方式、同步方式、检错方式。 应答方式、通信方式、包(帧)的构成。 位的调制方式(包括位时序条件)。 |
1 层:物理层 | 规定了通信时使用的电缆、连接器等的媒体、电气信号规格等,以实现设备间的信号传送。 如:信号电平、收发器、电缆、连接器等的形态。 |
CAN 协议只涵盖了 ISO 规定的 OSI基本参照模型中的传输层、数据链路层及物理层。数据链路层可以分为2个子层:LLC : Logical LinkControl (逻辑链路控制层)和MAC : Medium Access Control (媒介访问控制层)。CAN网络协议与ISO的OSI模型的对照如图2所示[2]。
图2 CAN协议与OSI对照图(图片来自参考文献2)
数据链路层的功能是将物理层收到的信号组织成有意义的消息,并提供传送错误控制等传输控制的流程。具体地说,就是消息的帧化、仲裁、应答、错误的检测或报告。数据链路层的功能通常在 CAN 控制器的硬件中执行。
2.2 博世CAN协议与ISO相应标准
前面曾提到CAN通讯最早是由博世公司提出的,最终发展成为ISO标准。博世发布的CAN2.0规范分为A和B两个部分,A 部分是对CAN 的报文格式说明,B 部分是对标准格式和扩展格式的说明。为了兼容CAN2.0,要求CAN 的仪器应兼容A 部分或B 部分。博世公司的CAN协议规范英文版可以在附录中给出的网址下载,其中文翻译版由周立功公司提供,可以在相应网站下载。
CAN 协议经 ISO 标准化后有 ISO11898 标准和 ISO11519-2 标准两种。ISO11898 和 ISO11519-2 标准对于数据链路层的定义相同,但物理层不同[2]。
(1) 关于 ISO11898-1
ISO11898 是通信速度为 125kbps-1Mbps 的 CAN 高速通信标准。
目前,ISO11898 追加新规约后,成为 ISO11898-1 新标准。
(2) 关于 ISO11519-2
ISO11519 是通信速度为 125kbps 以下的 CAN 低速通信标准。
ISO11519-2 是 ISO11519-1 追加新规约后的版本[2]。
图 3表示 CAN 协议和 ISO11898 及 ISO11519-2 标准的范围。
图3 CAN 协议和 ISO11898 及 ISO11519-2 标准(图片来自参考文献2)
2.3 CAN协议物理层
与I2C、SPI等具有时钟信号的同步通讯方式不同,CAN通讯并不是以时钟信号来进行同步的,它是一种异步通讯,只具有CAN_High和CAN_Low两条信号线,共同构成一组差分信号线,以差分信号的形式进行通讯。 CAN物理层的形式主要分为闭环总线(ISO11898)及开环总线网络(ISO11519-2)两种,一个适合于高速通讯,一个适合于远距离通讯。接下来将讨论两者在物理层的主要区别[1]。
下图4给出了CAN总线两种形式的连接图,后续将分别进行介绍。图中总线端部均有负载电阻RL,这些电阻用来抑制反射作用。一般不要把RL置于ECU内部,因为这样的话,断开一个内部置有RL的ECU同总线的链接时,总线就会失去终端[3]。
图4 CAN 总线及节点连接(图片来自参考文献2)
下图5给出了CAN网络的通信速度与总线长度的关系曲线
图5通信速度和最大总线长度(图片来自参考文献2)
2.3.1 闭环总线网络
CAN闭环通讯网络是一种遵循ISO11898标准的高速、短距离网络,它的总线最大长度为40m,通信速度最高为1Mbps,总线的两端各要求有一个“120欧”的电阻,如图6所示。
图6 CAN闭环总线通讯网络(图片来自参考文献1)
2.3.2 开环总线网络
CAN开环总线网络是遵循ISO11519-2标准的低速、远距离网络,它的最大传输距离为1km,最高通讯速率为125kbps,两根总线是独立的、不形成闭环,要求每根总线上各串联有一个“2.2千欧”的电阻。
图7 CAN开环总线通讯网络(图片来自参考文献1)
2.3.3 CAN协议中的差分信号
CAN总线上可以挂载多个通讯节点,节点之间的信号经过总线传输,实现节点间通讯。由于CAN通讯协议不对节点进行地址编码,而是对数据内容进行编码,所以网络中的节点个数理论上不受限制,只要总线的负载足够即可,可以通过中继器增强负载[1]。
CAN通讯节点由一个CAN控制器及CAN收发器组成,控制器与收发器之间通过CAN_Tx及CAN_Rx信号线相连,收发器与CAN总线之间使用CAN_High及CAN_Low信号线相连。其中CAN_Tx及CAN_Rx使用普通的类似TTL逻辑信号,而CAN_High及CAN_Low是一对差分信号线,使用比较特别的差分信号[1]。
当CAN节点需要发送数据时,控制器把要发送的二进制编码通过CAN_Tx线发送到收发器,然后由收发器把这个普通的逻辑电平信号转化成差分信号,通过差分线CAN_High和CAN_Low线输出到CAN总线网络。而通过收发器接收总线上的数据到控制器时,则是相反的过程,收发器把总线上收到的CAN_High及CAN_Low信号转化成普通的逻辑电平信号,通过CAN_Rx输出到控制器中[1]。
那问题来了,什么是差分信号?图8给出了模电中差模信号的标示方法。差分信号又称差模信号,与传统使用单根信号线电压表示逻辑的方式有区别,使用差分信号传输时,需要两根信号线,这两个信号线的振幅相等,相位相反,通过两根信号线的电压差值来表示逻辑0和逻辑1[1]。
图8 差模信号
为什么选择差分信号,差分信号有什么优点呢?
相对于单信号线传输的方式,使用差分信号传输具有如下优点[1]:
抗干扰能力强,当外界存在噪声干扰时,几乎会同时耦合到两条信号线上,而接收端只关心两个信号的差值,所以外界的共模噪声可以被完全抵消。
能有效抑制它对外部的电磁干扰,同样的道理,由于两根信号的极性相反,他们对外辐射的电磁场可以相互抵消,耦合的越紧密,泄放到外界的电磁能量越少。
时序定位精确,由于差分信号的开关变化是位于两个信号的交点,而不像普通单端信号依靠高低两个阈值电压判断,因而受工艺,温度的影响小,能降低时序上的误差,同时也更适合于低幅度信号的电路。
由于差分信号线具有这些优点,所以在USB协议、485协议、以太网协议及CAN协议的物理层中,都使用了差分信号传输。
CAN协议中的差分信号又是什么样子的呢?
CAN协议中对它使用的CAN_High及CAN_Low表示的差分信号做了规定。
以高速CAN协议为例,当表示逻辑1时(隐性电平),CAN_High和CAN_Low线上的电压均为2.5v,即它们的电压差VH-VL=0V;而表示逻辑0时(显性电平),CAN_High的电平为3.5V,CAN_Low线的电平为1.5V,即它们的电压差为VH-VL=2V[1]。
下表给出了高速闭环CAN和低速开环CAN的差分信号代表的意义。
表2 CAN 协议标准表示的信号逻辑(来自参考文献1)
现通过例子进行说明,以上图中ISO11898高速CAN隐性电平和显性电平的典型值进行说明。
如下图9所示,如果要传输TTL逻辑电平1(高电平),CAN_High线传输一个2.5V的电平,CAN_Low线传输一个2.5V的电平,则总线上其他节点接受到的信号是这两个电平的差值0V,但是在CAN协议中规定差值为0V时代表逻辑1。同理,右侧反映的是逻辑0的传输过程。
图9 CAN电平信号
前面提到显性电平和隐性电平,但是未做解释,在这里解释一下。
在CAN协议中规定逻辑1为隐性电平,逻辑0为显性电平。在CAN总线中,必须使它处于隐性电平(逻辑1)或显性电平(逻辑0)中的其中一个状态。假如有两个CAN通讯节点,在同一时间,一个输出隐性电平,另一个输出显性电平,类似I2C总线的“线与”特性将使它处于显性电平状态,显性电平的名字就是这样来的,即可以认为显性具有优先的意味[1]。
由于CAN总线协议的物理层只有1对差分线,在一个时刻只能表示一个信号,所以对通讯节点来说,CAN通讯是半双工的,收发数据需要分时进行。在CAN的通讯网络中,因为共用总线,在整个网络中同一时刻只能有一个通讯节点发送信号,其余的节点在该时刻都只能接收[1]。
2.3.4 高速CAN和低速CAN不同点汇总
现将高速CAN(ISO11898)和低速CAN(ISO11519-2)的主要不同点列于下表。
表3 CAN 协议标准表示的信号逻辑(来自参考文献1)
物理层 | ISO 11898(High speed) | ISO 11519-2(Low speed) |
通信速度 | 最高 1Mbps | 最高125kbps |
总线最大长度 | 40m/1Mbps | 1km/40kbps |
连接单元数 | 最大 30 | 最大 20 |
总线拓扑 | ||
物理层 | 双绞线(屏蔽/非屏蔽) 闭环总线 阻抗(Z):120Ω (Min.85Ω Max.130Ω) 总线电阻率(r):70mΩ/m 总线延迟时间:5ns/m 终端电阻:120Ω (Min.85ΩMax.130Ω) | 双绞线 (屏蔽/非屏蔽) 开环总线 阻抗(Ζ):120Ω (Min.85Ω Max.130Ω) 总线电阻率(Γ):90mΩ/m 总线延迟时间:5ns/m 终端电阻:2.20kΩ (Min.2.09kΩ Max.2.31kΩ) CAN_L 与GND 间静电容量 30pF/m CAN_H 与GND 间静电容量 30pF/m |
总线拓扑 |
2.4 CAN协议层
CAN的协议层规定了发送方如何发送报文,接受方如何接收报文,报文如何封装成数据帧,帧的类型及格式等内容。要完全掌握协议层,则需要从最基础的位时序着手。
2.4.1 位时序及位同步
表4段及其作用(来自参考文献2)
段名称 | 段的作用 | Tq 数 | |
同步段 (SS:Synchronization Segment) | 多个连接在总线上的单元通过此段实现时序 调整,同步进行接收和发送的工作。由隐性电 平到显性电平的边沿或由显性电平到隐性电平边沿最好出现在此段中。 | 1Tq | 8~25Tq |
传播时间段 (PTS: Propagation Time Segment) | 用于吸收网络上的物理延迟的段。 所谓的网络的物理延迟指发送单元的输出延 迟、总线上信号的传播延迟、接收单元的输入 延迟。 这个段的时间为以上各延迟时间的和的两倍。 | 1~8Tq | |
相位缓冲段1 (PBS1: Phase Buffer Segment 1) | 当信号边沿不能被包含于SS 段中时,可在此 段进行补偿。 由于各单元以各自独立的时钟工作,细微的时 钟误差会累积起来,PBS 段可用于吸收此误 差。 通过对相位缓冲段加减 SJW 吸收误差。(请 参照图34)。SJW 加大后允许误差加大,但 通信速度下降。 | 1~8Tq | |
相位缓冲段2 (PBS2: Phase Buffer Segment 2) | 2~8Tq | ||
再同步补偿宽度 (SJW: reSynchronization Jump Width) | 因时钟频率偏差、传送延迟等,各单元有同步 误差。SJW 为补偿此误差的最大值。 | 1~4Tq |
由于CAN属于异步通讯,没有时钟信号线,连接在同一个总线网络中的各个节点会像串口异步通讯那样,节点间使用约定好的波特率进行通讯,特别地,CAN还会使用“位同步”的方式来抗干扰、吸收误差,实现对总线电平信号进行正确的采样,确保通讯正常[1]。
为了实现位同步,CAN协议把每一个数据位的时序分解成同步段SS段、传播时间段PTS段、相位缓冲段PBS1段、相位缓冲段PBS2段,这四段的长度加起来即为一个CAN数据位的长度。这些段又由可称为 Time Quantum(以下称为Tq)的最小时间单位构成。1 位分为4 个段,每个段又由若干个Tq,这称为位时序,构成一个完整的位由8~25个Tq组成。1 位由多少个Tq 构成、每个段又由多少个Tq 构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点[2]。
表4先对各段的功能做一个汇总,看不懂没关系,后面将根据例子来讲解。看完例子以后再回头看看这份总结,会对位同步有更高层次的理解。
首先,来看下图10,上面的总线电平是按照bit为单位进行传输的。针对每一bit的时间长度,又可以分为更小的单位tq。如下图第一位逻辑0可以分为4段,总共19个tq。其中SS段占1Tq,PTS段占6Tq,PBS1段占5Tq,PBS2段占7Tq。信号的采样点位于PBS1段与PBS2段之间,通过控制各段的长度,可以对采样点的位置进行偏移,以便准确地采样[1]。
图10 CAN 位时序分解图(来自参考文献1)
l SS段(SYNC SEG)
SS译为同步段,若通讯节点检测到总线上信号的跳变沿被包含在SS段的范围之内,则表示节点与总线的时序是同步的,当节点与总线同步时,采样点采集到的总线电平即可被确定为该位的电平。SS段的大小固定为1Tq。这里,可能会有两种情况:1.总线上两个或者两个以上的连续bit 是同一个逻辑电平,则SS段内是没有电平跳变的,也就无法判定是否与总线同步。2.SS段内有下降沿电平或者上升沿电平跳变,此时,可以判定是否同步[1]。
PTS段(PROP SEG)
PTS译为传播时间段,这个时间段是用于补偿网络的物理延时时间。是总线上输入比较器延时和输出驱动器延时总和的两倍。PTS段的大小可以为1~8Tq[1]。
PBS1段(PHASE SEG1),
PBS1译为相位缓冲段,主要用来补偿边沿阶段的误差,它的时间长度在重新同步的时候可以加长。PBS1段的初始大小可以为1~8Tq[1]。
PBS2段(PHASE SEG2)
PBS2这是另一个相位缓冲段,也是用来补偿边沿阶段误差的,它的时间长度在重新同步时可以缩短。PBS2段的初始大小可以为2~8Tq[1]。
2.4.2 通讯波特率计算
首先要弄明白以下三个概念:
码元:在数字通信中常常用时间间隔相同的符号来表示数字。这样的时间间隔内的信号称为码元,这个时间间隔称为码元长度。
波特率:表示每秒钟传输的码元个数。
比特率:每秒钟传输的二进制位数,单位为比特每秒(bit/s)。
大多数人看完以上的文字描述,还是一头雾水。那下面通过例子来说明。
情形1:现在要表示0V和3.3V两种电压状态,0V用逻辑0表示,3.3V用逻辑1来表示。假设有一个传感器在1s内采集8次电压数据并进行8次AD转化后输给单片机,则单片机接受到的数据可能是 01010101(举例),其代表传感器8次采样的电压值在0与3.3V之间交替变化。这种情况下0V这个信号称为一个码元,3.3V信号也为一个码元。传输0V需要传输一位逻辑0,传输3.3V需要传输一位逻辑1,他们需要的时间是相同的。这个例子中,比特率=8=波特率;
情形2:现在有4个电压值需要传输,分别是0V、2V、4V、6V。我们设置对应的符号来表示这4个数字,0Và00、2Và01、4Và10、6Và11。这样就用2个比特位表示一个数字。传输2个比特位(一个数字或码元)时间相同,如果1s内还是采样8次,电压从低到高循环,那单片机得到的数值可能为0001 10 11 00 01 10 11。此时,比特率=16bit/s=2*波特率。
以下有关CAN通讯波特率的计算都是假设一个码元用一个比特位表示的情形。
现假设汽车的传动CAN的通讯速率设定为500Kbps,每一位包含16个tq,则时间tq计算如下。
tq=(1/500000)/16=0.125us
反过来,已知tq及每数据位包含的tq数量,就可以计算出CAN总线的波特率。
2.4.3 硬同步
CAN 协议的通信方法为NRZ(Non-Return to Zero)方式。各个位的开头或者结尾都没有附加同步信号。发送单元以与位时序同步的方式开始发送数据。另外,接收单元根据总线上电平的变化进行同步并进行接收工作。但是,发送单元和接收单元存在的时钟频率误差及传输路径上的(电缆、驱动器等)相位延迟会引起同步偏差。因此接收单元通过硬件同步或者再同步的方法调整时序进行接收[2]。
接收单元在总线空闲状态检测出帧起始时进行的同步调整。在检测出边沿的地方不考虑SJW 的值而认为是SS 段。硬件同步的过程如图11所示。
图11硬同步(来自参考文献2)
在总线出现起始信号时,该节点原来的位时序与总线的时序不同步(如图中原SS段与SOF下降沿不同步),因此这个状态下采样点采集得到的数据是不正确的;节点以硬同步的方式调整,把自己的位时序中的SS段平移至总线出现下降沿的位置,获得同步,这时采样得到的数据才是正确的[2]。
2.4.4 再同步
因为硬同步时只是在帧起始信号时起作用,无法确保后续一连串的位时序都是同步的,所以CAN还引入了再同步方式。在接收过程中检测出总线上的电平变化时进行的同步调整。每当检测出边沿时,根据SJW值通过加长PBS1 段,或缩短PBS2 段,以调整同步。但如果发生了超出SJW值的误差时,最大调整量不能超过SJW值[2]。
图12隐性电平到显性电平的边沿出现在PTS和PBS1之间(SJW=2,来自参考文献2)
图13隐性电平到显性电平的边沿出现在PBS2中(SJW=2,来自参考文献2)
2.4.5 调整同步
硬件同步和再同步遵从如下规则[2]。
(1) 1 个位中只进行一次同步调整。
(2) 只有当上次采样点的总线值和边沿后的总线值不同时,该边沿才能用于调整同步。
(3) 在总线空闲且存在隐性电平到显性电平的边沿时,则一定要进行硬件同步。
(4) 在总线非空闲时检测到的隐性电平到显性电平的边沿如果满足条件(1)和(2),将进行再同步。但还要满足下面条件。
(5) 发送单元观测到自身输出的显性电平有延迟时不进行再同步。
(6) 发送单元在帧起始到仲裁段有多个单元同时发送的情况下,对延迟边沿不进行再同步。
2.5 CAN帧的种类
通信是通过以下 5 种类型的帧进行的。
数据帧
遥控帧
错误帧
过载帧
帧间隔
另外,数据帧和遥控帧有标准格式(CAN2.0A)和扩展格式(CAN2.0B)两种格式。标准格式有11 个位的标识(Identifier: 以下称ID),扩展格式有29 个位的ID。
下表5给出了帧的种类和用途。
表5帧种类及其作用(来自参考文献2)
帧 | 帧用途 |
数据帧 | 用于发送单元向接收单元传送数据的帧。 |
遥控帧 | 用于接收单元向具有相同 ID 的发送单元请求数据的帧。 |
错误帧 | 用于当检测出错误时向其它单元通知错误的帧。 |
过载帧 | 用于接收单元通知其尚未做好接收准备的帧。 |
帧间隔 | 用于将数据帧及遥控帧与前面的帧分离开来的帧。 |
2.5.1 数据帧
如下图14所示,数据帧由7 个段构成。
图14数据帧结构(来自参考文献2并经过优化)
帧起始(Start ofFrame, SOF):由一个显性位构成,只有在总线处于空闲状态时,才允许开始发送。所有站必须同步于首先开始发送的那个站的帧起始前沿。
仲裁段:表示数据的优先级。在标准格式中,仲裁场由11位标识符合RTR位组成;在扩展格式中,仲裁段由29位标识符和SRR位、标识符以及RTR位组成。当同时有两个报文被发送时,总线会根据仲裁段的内容决定哪个数据包能被传输,这也是它名称的由来。在CAN协议中,ID起着重要的作用,它决定着数据帧发送的优先级,也决定着其它节点是否会接收这个数据帧。CAN协议不对挂载在它之上的节点分配优先级和地址,对总线的占有权是由信息的重要性决定的,即对于重要的信息,可给它打包上一个优先级高的ID,使它能够及时地发送出去。也正因为它这样的优先级分配原则,使得CAN的扩展性大大加强,在总线上增加或减少节点并不影响其它设备。报文的优先级,是通过对ID的仲裁来确定的。根据前面对物理层的分析我们知道如果总线上同时出现显性电平和隐性电平,总线的状态会被置为显性电平,CAN正是利用这个特性进行仲裁。若两个节点同时竞争CAN总线的占有权,当它们发送报文时,若首先出现隐性电平,则会失去对总线的占有权,进入接收状态。在开始阶段,两个设备发送的电平一样,所以它们一直继续发送数据。到了图中箭头所指的时序处,节点单元1发送的为隐性电平,而此时节点单元2发送的为显性电平,由于总线的“线与”特性使它表达出显示电平,因此单元2竞争总线成功,这个报文得以被继续发送出去。仲裁段ID的优先级也影响着接收设备对报文的反应。因为在CAN总线上数据是以广播的形式发送的,所有连接在CAN总线的节点都会收到所有其它节点发出的有效数据,因而CAN控制器大多具有根据ID过滤报文的功能,它可以控制自己只接收某些ID的报文[1]。
图15数据帧仲裁过程(来自参考文献1)
RTR位(Remote Transmission Request Bit),译作远程传输请求位,它是用于区分数据帧和遥控帧的,当它为显性电平时表示数据帧,隐性电平时表示遥控帧[1]。
IDE位(Identifier Extension Bit),译作标识符扩展位,它是用于区分标准格式与扩展格式,当它为显性电平时表示标准格式,隐性电平时表示扩展格式[2]。
SRR位(Substitute Remote Request Bit),只存在于扩展格式,它用于替代标准格式中的RTR位。由于扩展帧中的SRR位为隐性位,RTR在数据帧为显性位,所以在两个ID相同的标准格式报文与扩展格式报文中,标准格式的优先级较高[3]。
控制段:在控制段中的r1和r0为保留位,默认设置为显性位。它最主要的是DLC段(Data Length Code),译为数据长度码,它由4个数据位组成,用于表示本报文中的数据段含有多少个字节,DLC段表示的数字为0~8。但接收方对DLC = 9~15 的情况并不视为错误[2]。
表6数据长度和字节关系(来自参考文献2)
数据段:数据段为数据帧的核心内容,它是节点要发送的原始信息,由0~8个字节组成,MSB先行[2]。
CRC段:为了保证报文的正确传输,CAN的报文包含了一段15位的CRC校验码,一旦接收节点算出的CRC码跟接收到的CRC码不同,则它会向发送节点反馈出错信息,利用错误帧请求它重新发送。CRC部分的计算一般由CAN控制器硬件完成,出错时的处理则由软件控制最大重发数。在CRC校验码之后,有一个CRC界定符,它为隐性位,主要作用是把CRC校验码与后面的ACK段间隔起来[1]。
ACK段:ACK段包括一个ACK槽位,和ACK界定符位。类似I2C总线,在ACK槽位中,发送节点发送的是隐性位,而接收节点则在这一位中发送显性位以示应答。在ACK槽和帧结束之间由ACK界定符间隔开[1]。
帧结束:EOF段(End Of Frame),译为帧结束,帧结束段由发送节点发送的7个隐性位表示结束[1]。
2.5.2 遥控帧
接收单元向发送单元请求发送数据所用的帧。遥控帧由 6 个段组成。遥控帧没有数据帧的数据段。遥控帧的构成如图16所示。
图16遥控帧结构(来自参考文献2,经过优化)
帧起始(SOF)
表示帧开始的段。
仲裁段
表示该帧优先级的段。可请求具有相同 ID 的数据帧。
控制段
表示数据的字节数及保留位的段。
CRC 段
检查帧的传输错误的段。
ACK 段
表示确认正常接收的段。
帧结束
表示遥控帧结束的段。
下面总结数据帧和遥控帧的不同[2]
1. 遥控帧的RTR 位为隐性位,没有数据段。
没有数据段的数据帧和遥控帧可通过RTR 位区别开来。
2.遥控帧没有数据段,数据长度码该如何表示?
遥控帧的数据长度码以所请求数据帧的数据长度码表示。
3.没有数据段的数据帧有何用途?
例如,可用于各单元的定期连接确认/应答、或仲裁段本身带有实质性信息的情况下。
2.5.3 错误帧
用于在接收和发送消息时检测出错误通知错误的帧。错误帧由错误标志和错误界定符构成。
错误帧的构成如图 17 所示。
图17错误帧结构
(1) 错误标志
错误标志包括主动错误标志和被动错误标志两种。
主动错误标志:6 个位的显性位。
被动错误标志:6 个位的隐性位。
(2) 错误界定符
错误界定符由 8 个位的隐性位构成。
2.5.4 过载帧
过载帧是用于接收单元通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。
过载帧的构成如图 18所示。
图18过载帧
(1) 过载标志
6 个位的显性位。
过载标志的构成与主动错误标志的构成相同。
(2) 过载界定符
8 个位的隐性位。
过载界定符的构成与错误界定符的构成相同。
2.5.5帧间隔
帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。
过载帧和错误帧前不能插入帧间隔。
图19帧间隔
2.6优先级的决定
在总线空闲态,最先开始发送消息的单元获得发送权。
多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。
图20 ID仲裁过程(来自参考文献2)
数据帧和遥控帧的优先级
具有相同 ID 的数据帧和遥控帧在总线上竞争时,仲裁段的最后一位(RTR)为显性位的数据帧具有优先权,可继续发送。
数据帧和遥控帧的仲裁过程如图
图21 RTR仲裁(来自参考文献2)
标准格式和扩展格式的优先级
标准格式 ID 与具有相同ID 的遥控帧或者扩展格式的数据帧在总线上竞争时,标准格式的RTR 位为显性位的具有优先权,可继续发送。
标准格式和扩展格式的仲裁过程如图22。
图22标准格式与扩展格式仲裁(来自参考文献2)
2.7 位填充
CAN总线采用多种抗干扰措施以减少消息帧在传送过程中出错,位填充技术是其中很重要的一种。在CAN的消息帧中,帧起始、仲裁段、控制段、数据段和CRC序列帧段均以位填充方法进行编码。数据帧或远程帧的其余位场(CRC界定符、ACK场和帧结束)为固定形式,不进行位填充。当发送器在发送位流中检测到5个极性相同的连续位时,它在实际发送时,自动插入一个补码[3]。
图23位填充原理图
举例说明一下:假如要传输的数据中有0x00这个数据,其对应的二进制码是0000 0000,那么该字节数据在传输时将被替换成0000 0100,接收方会自动过滤填充位。一般过滤过程在接收方的CAN控制器中自动完成。
另,如图22,共有3个填充位,其中第3个填充位之前的5个连续的相同的极性位中包含第2个填充位。可见在实施填充位技术时,填充位也被当做总线数据位处理。
2.8 CRC校验原理
循环冗余校验(CyclicRedundancy Check, CRC)的根本思想是先在要发送的帧后面附加一个数(这个数就是CAN数据帧数据段后面的15位CRC码),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除,在CAN协议中这个特定的数是1100 0101 10011001(其构成多项式X15+X14+X10+X8+X7+X4+X3+1)。到达接收端后,再把接收到的新帧除以这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理,所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。
以CAN标准数据帧为例,将帧起始、仲裁段、控制段、数据段组合起来看做P(X),因为CAN协议中CRC校验位给定的是15位(不包含CRC界定符),所以在P(X)二进制数据后面加上15位的0,新组成的数据帧应该为Q(X),令G(X)= X15+X14+X10+X8+X7+X4+X3+1。现在,Q(X)为被除数,G(X)为除数,R(X)是 Q(X)与G(X)进行模2运算获得的余数。也就是该帧的CRC校验码,也称之为FCS(帧校验序列)。但要注意的是,余数的位数一定要是比除数位数少一位且仅能少一位,哪怕前面位是0,甚至是全为0也都不能省略。
最后发送的数据帧是把这个校验码R(X)附加在原数据帧P(X)后面,构建一个新帧发送到接收端;最后在接收端再把这个新帧以“模2除法”方式除以前面选择的除数G(X),如果没有余数,则表明该帧在传输过程中没出错,否则出现了差错。
为了便于理解,从网络上摘取了一个CRC校验码的计算实例,内容来自http://blog.51cto.com/winda/1063951,详细内容可访问该博客。
现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。下面是具体的计算过程:
(1)首先把生成多项式转换成二进制数,由G(X) = X4 + X3 + 1可以知道(,它一共是5位(总位数等于最高位的幂次加1,即4+1=5),然后根据多项式各项的含义(多项式只列出二进制值为1的位,也就是这个二进制的第4位、第3位、第0位的二进制均为1,其它位均为0)很快就可得到它的二进制比特串为11001。
(2)因为生成多项式的位数为5,根据前面的介绍,得知CRC校验码的位数为4(校验码的位数比生成多项式的位数少1)。因为原数据帧10110011,在它后面再加4个0,得到101100110000,然后把这个数以“模2除法”方式除以生成多项式,得到的余数(即CRC码)为0100,如图24所示。注意参考前面介绍的“模2除法”运算法则。
图24模2运算过程
(3)把上步计算得到的CRC校验0100替换原始帧101100110000后面的四个“0”,得到新帧101100110100。再把这个新帧发送到接收端。
(4)当以上新帧到达接收端后,接收端会把这个新帧再用上面选定的除数11001以“模2除法”方式去除,验证余数是否为0,如果为0,则证明该帧数据在传输过程中没有出现差错,否则出现了差错。
2.9 错误的种类
错误共有 5 种。多种错误可能同时发生[2]。
• 位错误
• 填充错误
• CRC 错误
• 格式错误
• ACK 错误
错误的种类、错误的内容、错误检测帧和检测单元如表 7所示。
表7错误种类(来自参考文献2)
错误的种类 | 错误的内容 | 错误的检测帧(段) | 检测单元 |
位错误 | 比较输出电平和总线电平(不含填充位),当两电平不一样时所检测到的错误。 | •数据帧(SOF∼EOF) • 遥控帧(SOF∼EOF) • 错误帧 • 过载帧 | 发送单元 接收单元 |
填充错误 | 在需要位填充的段内,连续检测到 6位相同的电平时所检测到的错误。 | •数据帧(SOF∼CRC 顺序) •遥控帧(SOF∼CRC 顺序) | 发送单元 接收单元 |
CRC 错误 | 从接收到的数据计算出的 CRC 结果与接收到的CRC 顺序不同时所检测到的错误。 | •数据帧(CRC 顺序) •遥控帧(CRC 顺序) | 接收单元 |
格式错误 | 检测出与固定格式的位段相反的格式时所检测到的错误。 | •数据帧(CRC 界定符、ACK 界定符、EOF) •遥控帧(CRC 界定符、ACK 界定符、EOF) •错误界定符 •过载界定符 | 接收单元 |
ACK 错误 | 发送单元在ACK槽(ACK Slot)中检测出隐性电平时所检测到的错误(ACK没被传送过来时所检测到的错误)。 | •数据帧(ACK 槽) •遥控帧(ACK 槽) | 发送单元 |
(1) 位错误
位错误由向总线上输出数据帧、遥控帧、错误帧、过载帧的单元和输出ACK 的单元、输出错误的单元来检测。
在仲裁段输出隐性电平,但检测出显性电平时,将被视为仲裁失利,而不是位错误。
在仲裁段作为填充位输出隐性电平时,但检测出显性电平时,将不视为位错误,而是填充错误。
发送单元在ACK 段输出隐性电平,但检测到显性电平时,将被判断为其它单元的ACK 应答,而非位错误。
输出被动错误标志(6 个位隐性位)但检测出显性电平时,将遵从错误标志的结束条件,等待检测出连续相同6 个位的值(显性或隐性),并不视为位错误。
(2) 格式错误
即使接收单元检测出EOF(7 个位的隐性位)的最后一位(第8 个位)为显性电平,也不视为格式错误。
即使接收单元检测出数据长度码(DLC)中9∼15 的值时,也不视为格式错误。
检测出满足错误条件的单元输出错误标志通报错误。
处于主动错误状态的单元输出的错误标志为主动错误标志;处于被动错误状态的单元输出的错误标志为被动错误标志。
发送单元发送完错误帧后,将再次发送数据帧或遥控帧。
错误标志输出时序如表8所示。
表8错误标志输出时序(参考文献2)
错误的种类 | 输出时序 |
位错误 填充错误 格式错误 ACK 错误 | 从检测出错误后的下一位开始输出错误标志。 |
CRC 错误 | ACK界定符后的下一位开始输出错误标志。 |
2.10错误状态的种类
错误状态的种类[2]。
单元始终处于 3 种状态之一。
(1) 主动错误状态
主动错误状态是可以正常参加总线通信的状态。
处于主动错误状态的单元检测出错误时,输出主动错误标志。
(2) 被动错误状态
被动错误状态是易引起错误的状态。
处于被动错误状态的单元虽能参加总线通信,但为不妨碍其它单元通信,接收时不能积极地发送错误通知。处于被动错误状态的单元即使检测出错误,而其它处于主动错误状态的单元如果没发现错误,整个总线也被认为是没有错误的。
处于被动错误状态的单元检测出错误时,输出被动错误标志。
另外,处于被动错误状态的单元在发送结束后不能马上再次开始发送。在开始下次发送前,在间隔帧期间内必须插入“延迟传送”(8 个位的隐性位)。
(3) 总线关闭态
总线关闭态是不能参加总线上通信的状态。
信息的接收和发送均被禁止。
这些状态依靠发送错误计数和接收错误计数来管理,根据计数值决定进入何种状态。错误状态和计数值的关系如表9 及图25所示。
表9错误状态和计数值(来自参考文献2)
单元错误状态 | 发送错误计数值(TEC) | 接收错误计数值(REC) |
主动错误状态 | 0~127 且0~127 | |
被动错误状态 | 128~255 或128~255 | |
总线关闭态 | 256~—— |
图25单元的错误状态
错误计数值
发送错误计数值和接收错误计数值根据一定的条件发生变化。
错误计数值的变动条件如表10所示。
一次数据的接收和发送可能同时满足多个条件。
错误计数器在错误标志的第一个位出现的时间点上开始计数。
表10错误计数值的变动条件(来自参考文献2)
接受和发送错误计数值的变动条件 | 发送错误计数值 (TEC) | 接收错误计数值 (REC) | |
1 | 接收单元检测出错误时。 例外:接收单元在发送错误标志或过载标志中检测出“位错误”时,接收错误计数值不增加。 | — | +1 |
2 | 接收单元在发送完错误标志后检测到的第一个位为显性电平时。 | — | +8 |
3 | 发送单元在输出错误标志时。 | +8 | — |
4 | 发送单元在发送主动错误标志或过载标志时,检测出位错误。 | +8 | — |
5 | 接收单元在发送主动错误标志或过载标志时,检测出位错误。 | — | +8 |
6 | 各单元从主动错误标志、过载标志的最开始检测出连续14个位的显性位时。之后,每检测出连续的 8 个位的显性位时。 | 发送时 +8 | 接收时 +8 |
7 | 检测出在被动错误标志后追加的连续8 个位的显性位时。 | 发送时 +8 | 接收时 +8 |
8 | 发送单元正常发送数据结束时(返回ACK 且到帧结束也未检测出错误时)。 | −1 TEC=0 时±0 | — |
9 | 接收单元正常接收数据结束时(到CRC 未检测出错误且正常返回ACK 时)。 | — | 1≤REC≤127 时-1 REC=0 时±0 REC>127 时设 REC=127 |
10 | 处于总线关闭态的单元,检测到128 次连续11 个位的隐性位。 | TEC=0 | REC=0 |
上面是使用专业术语阐述的错误状态,很多人看完后并不能完全理解。本手册将采用一种比喻的方式重新进行阐述。
我们将三种错误状态比喻成流水线上的工人状态。CAN总线比喻成流水线,流水上上每一个工位的工人代表一个节点。刚开始通讯的时候节点都被初始化,工人精神饱满,通讯正常,产品从一个工人正确输送到另一个工人。但是,随着时间的推移,某个工人在自己的工位组装产品(报文)时,发现自己组装错了零件,他是主动发现的,为了把这一信息传给其他工人,他主动发出一条信息(6个显性位),也就是主动错误标志,同时发送错误计数值TEC根据错误类型递增,这被称为主动错误状态。其他节点也有类似的功能。
同样是该工人,如果他接收到上一个工人发过来的产品,但是检查出上个工人装错了零件,他发送接收错误标志,同时接收错误计数值REC递增。当TEC或者REC的计数值大于127时,该工人(节点)被认为能力不行,他从一级工人(主动错误状态)被降级为二级工人(被动错误状态)。当然,这个过程中,TEC和REC并不是一直递增的,当该节点正确发送或者接受一次信息,TEC和REC相应的会递减。
成为二级工人(被动错误状态)后,一些权力被限制了,他即使发现了别人组装的产品有错误,也不能主动报出该信息,只能等着其他一级工人报出该信息。他的TEC和REC仍然按照规定递增或递减。当TEC和REC的值都递减到127以下时,他就又可以恢复一级工人的身份和得到相应权利。但是,如果他继续犯错使得TEC>255,那么他就被强制从产线上下来,不允许在参加通讯,也就是降为三级工人(总线关闭状态)。
由于失去了工作的机会,三级工人也就没有机会通过组装更多正确的产品来降低自己的TEC值,也就是处于总线关闭状态的节点无法回到被动错误状态。该工人只能接受技能培训,待技能提高后重新作为一级工人上线(TEC和REC重新置零)。这个等待在CAN协议里面一般是128个连续11位的隐性位。
3. CAN协议的特点
CAN 协议具有以下特点。
(1) 多主控制
在总线空闲时,所有的单元都可开始发送消息(多主控制)。
最先访问总线的单元可获得发送权(CSMA/CA方式)。
多个单元同时开始发送时,发送高优先级 ID 消息的单元可获得发送权。
(2) 消息的发送
在 CAN 协议中,所有的消息都以固定的格式发送。总线空闲时,所有与总线相连的单元都可以开始发送新消息。两个以上的单元同时开始发送消息时,根据标识符(Identifier 以下称为 ID)决定优先级。ID 并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始发送消息时,对各消息ID 的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。
(3) 系统的柔软性
与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。
(4) 通信速度
根据整个网络的规模,可设定适合的通信速度。
在同一网络中,所有单元必须设定成统一的通信速度。即使有一个单元的通信速度与其它的不一样,此单元也会输出错误信号,妨碍整个网络的通信。不同网络间则可以有不同的通信速度。
(5) 远程数据请求
可通过发送“遥控帧” 请求其他单元发送数据。
(6) 错误检测功能·错误通知功能·错误恢复功能
所有的单元都可以检测错误(错误检测功能)。
检测出错误的单元会立即同时通知其他所有单元(错误通知功能)。
正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。
(7) 故障封闭
CAN 可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
(8) 连接
CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。
参考文献
[1] 秉火团队.零死角玩转STM32-基于野火F103霸道开发板[M].深圳
[2]瑞萨科技. CAN总线入门手册[M]