文章目录
一、什么是CAN总线
CAN是Contorller Area Network的首字母缩写,意思是控制器局域网。它是一种国际标准化(ISO)的串行通信协议,常被称为CAN总线。CAN总线使用双绞线方式来传输信号,是世界上应用最广泛的现场总线之一。CAN常用于汽车中各种不同电子单元之间的通信,用来取代昂贵而笨重的配电线束。CAN通信协议的开发,使车上的多种ECU(电子控制单元)能够进行数据交换。 下图是瑞萨CAN入门文档提供的车载网络构想图。
1、CAN总线的特点:
- 传输距离远:CAN总线数据传输距离可以非常远,理论最高可达10公里。
- 灵活性比较强:CAN报文ID和数据内容可以任意更改,灵活性非常强。
- 多主控模式:每个节点都可以向总线发送报文且能接收到来自其他所有节点的所有消息。
- 连接节点多且节点易添加:连接节点可以很多个,且节点易添加,只需要将CANH和CANL接入CAN总线即可,新接入的节点不会影响其他节点发送和接收报文。
- 独特的仲裁机制:报文消息根据ID的值优先发送。ID越低优先级越高。发送失败的帧会自动重传。
- 故障封闭功能:当某一个节点产生太多错误会干扰到CAN总线其他设备时,这个节点可自动离线(进入BusOff状态)。
- 传输速率快:CAN数据传播速率非常快,普通CAN最高可达1Mbps(CANFD或CANXL可以更快)。
- 抗干扰能力强:CAN线采用双绞线差分形式,其抗噪声能力很强,不容易出现问题。
CAN也因为简单、可靠、高效..等等优点被使用广泛于自动化控制以及工业领域中。
2、CAN的发展史:
- 1983年,Bosch开始研究汽车网络技术
- 1986年,Bosch在SAE大会正式公布CAN的协议
- 1987年,Intel和Philips公司先后推出CAN控制器芯片
- 1991年,Bosch颁布CAN2.0技术规范
- 1991年,CAN总线最新在Benz S系列轿车上实现
- 1993年,ISO颁布CAN国际标准ISO-11898
- 1994年,由CiA组织举办第一届国际CAN大会(iCC)
- 2015年,CAN FD的ISO标准化
- 2021年,CAN XL第三代使用的规范CIA-610
二、CAN的OSI基本参照模型
控制器局域网(CAN)是一种串行通信协议,它有效地支持分布式实时控制,具有非常高的安全性。根据官方文档描述,为了实现设计的透明性和实现的灵活性,CAN协议示涵盖了ISO规定的OSI基本参照模型中的物理层、数据链路层、传输层。
1、物理层
CAN物理层定义了信号实际的发送方式、位时序、位的编码方式及同步的步骤。但具体地说,信号电平、通信 速度、采样点、驱动器和总线的电气特性、连接器的形态等均未定义。总结来说就是 CAN的物理层定义了CAN信号实际传输的方式。
一条CAN总线上可以挂载多个使用CAN设备的电子单元,也就是一条CAN总线可以有多个CAN节点,一般需要在最远的两端节点的CANH和CANL之间并联一个120Ω的电阻,并入的电阻一般称为CAN终端电阻。
但是根据传输速率(波特率)和传输距离的不同,并入的CAN终端电阻也是不同的,下图就是瑞萨给出的ISO11898和ISO11519-2物理层的异同点。
CAN信号的传输线分为CANH和CANL。CANH和CANL采用双绞的方式来传输信号。双绞线如下图。
CANH对地的电压一般在2.5V~4V,CANL对地的电压一般在2.5V~1V。
CAN信号是差分信号,总线电平分为显性电平和隐性电平。总线必须处于两种电平之一。总线执行逻辑上的线“与”时,显性电平为 0,隐性电平为 1。“显性”具有“优先”的意味,只要有一个单元输出显性电平,总线上即为显性电平。并且,“隐 性”具有“包容”的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平。(显性电平比性电平更强)
CAN总线为隐性电平时(逻辑1),CANH和CANL应都为2.5V(CANH和CANL之间压差为0V左右);
CAN总线为显性电平时(逻辑0),CANH为3.5V,CANL为1.5V(CANH和CANL之间压差为2V左右);
2、数据链路层
数据链路层分为MAC子层和LLC子层,MAC子层是CAN协议的核心部分。数据链路层的功能是将物理层收到的信号组织成有意义的消息,并提供传送错误控制等传输控制的流程。具体地说,就是消息的帧化、仲裁、 应答、错误的检测或报告。数据链路层的功能通常在CAN控制器的硬件中执行。
三、CAN的帧类型
CAN通信一般是基于以下五种帧进行的:
- 数据帧:用于发送单元向接收单元传送数据的帧。
- 遥控帧:用于接收单元向具有相同ID的发送单元请求数据的帧。
- 错误帧:用于当检测出错误时向其它单元通知错误的帧。
- 过载帧:用于接收单元通知其尚未做好接收准备的帧。
- 帧间隔:用于将数据帧及遥控帧与前面的帧分离开来的帧。
1、数据帧
数据帧分为两种帧格式,一种是标准帧格式,一种是扩展帧格式。标准帧格式有11位的标识符(Identifier: 以下称ID),而扩展帧格式29位的标识符。
CAN2.0A规定了11位标识符的标准帧格式。
CAN2.0B在CAN2.0A的基础上,增加了一种具有29位标识符的扩展帧格式。
一个有效的CAN数据帧,需要包含 帧起始段(SOF),仲裁段、控制段、数据段、CRC段、ACK段、以及帧结束。
- 帧起始段(SOF):标志着一个帧的开始,由一个显性位(0)构成,只有在总线空闲的时候发送。
- 仲裁段:标准帧的仲裁段和扩展帧的仲裁段是不一样的。在标准帧中,仲裁段由11位的标识符和RTR位构成(禁止高7位都是显性电平0)。而在扩展帧中,仲裁段由29位标识符、SRR位、IDE位、RTR位共同组成。
- 标识符(ID):用来确定一条报文,表明报文含义及优先级。(标识符我们一般称为“报文ID”)。标识符之所以被包含在仲裁段,是因为CAN的仲裁机制是根据标识符(ID)进行的。当总线空闲时,CAN总线上的节点才可以向总线发送报文,但当两个或多个节点同时向总线上发送报文时,CAN就会根据仲裁机制,对标识符(ID)和RTR位逐位处理,报文标识符(ID)小的拥有优先发送权,而报文标识符(ID)大的报文,则是在下一个总线空闲的时候尝试重发。
- RTR(远程传送请求位):数据帧RTR位必须为显性电平(0),远程帧RTR位必须为隐性电平(1)。
- IDE(标识符扩展位):在标准帧中,IDE属于控制段且IDE为显性电平(0)。在扩展帧中,IDE属于仲裁段,IDE为隐性电平(1)。
- 控制段:由6位组成。在标准帧中,控制段包括IDE(IDE=0)、保留位r0(r0=0)以及占4个bit的数据长度码DLC。在扩展帧中,控制段没有IDE位,而是两个保留位r0和r1(均为显性电平)。
- 数据段:数据段包含CAN报文所要发送的数据,由0~8个byte组成(具体为几个byte由控制段中的DLC决定)。从MSB(最高位)开始输出。我们在实际解析报文数据的时候,获取到报文数据后需要根据解析规则,按照Intel(LSB)格式去解析数据,或者根据Motorola(MSB)格式去解析数据。
- CRC段:CRC段是检查帧传输错误的帧,由CRC序列和CRC界定符DEL组成。CRC序列是根据多项式生成的CRC值,CRC的计算范围包括帧起始、仲裁段、控制段和数据段。CRC校验是为了通信双方的安全可靠性所制定的,只有发送方根据发送信息计算出的CRC序列和接收方根据接收信息所计算出的CRC值一致时,才能说明这次通信是成功的,否则就会报错。CRC界定符是用于将CRC段和ACK段分隔的位(始终为隐性电平)。
- ACK段:ACK段分为ACK槽和ACK界定符。发送节点的ACK槽为隐性电平。接收节点在接收到正确的信息后,会在ACK槽发送显性电平,通知发送单元正常接收结束。这称作“发送ACK”或者“返回ACK”(发送ACK的是在既不处于总线关闭态也不处于休眠态的所有接收节点中,接收到正常消息的节点。所谓正常消息是指不含填充错误、格式错误、CRC错误的消息)。ACK界定符用于将ACK段和帧结束(EOF)隔开(始终为隐性电平)。总结来说就是有节点正确接收到报文时,ACK=0、DEL=1;未正确接收到报文时,ACK和DEL都保持为1。
- 帧结束(EOF):帧结束表示该该帧的结束的段。由7个位的隐性位构成。节点在监测到11个连续的隐形电平后才会认为总线空闲。
需要注意的是在在发送数据帧(或者遥控帧)时,如果帧起始~CRC段之间的数据,连续5个位都是相同的电平,那么在下一个位(第6个位)则要插入1位与前5位反型的电平。在接收数据帧,如果帧起始~CRC段之间的数据,连续5个位都是相同的电平,需要删除下一个位(第6个位)再接收。如果这个第6个位的电平与前5位相同,将被视为错误并发送错误帧。
2、遥控帧
接收单元向发送单元请求发送数据所用的帧。遥控帧由6个段组成。遥控帧没有数据帧的数据段且RTR为隐性电平(1)。
- 数据帧和遥控帧的不同:遥控帧的RTR位为隐性位,没有数据段;没有数据段的数据帧和遥控帧可通过RTR位区别开来。
- 遥控帧的数据长度码以所请求数据帧的数据长度码表示。
- 遥控帧可用于各单元的定期连接确认/应答、或仲裁段本身带有实质性信息的情况。
3、错误帧
当节点检测到一个或多个由CAN标准所定义的错误时,就会产生一个错误帧。错误帧由错误标志和错误界定符构成。当一个节点在检测到错误条件时,通过发送错误帧来表示。比如当某个CAN报文的违反了比特填充法(具体需要参照博士的CAN官方文档),它会监测从帧起始到CRC分隔符的所有字段,也会检查ACK段和帧结束段。当某一帧出现问题时,所有节点都会检测到错误条件,并开始发送错误帧。实际上总线上的错误帧是由各个节点传输的不同错误标志叠加而成的。错误标志的总长度在最小为六位,最大为十二位。
- 错误标志:错误标志包括主动错误标志和被动错误标志两种。主动错误标志是处于主动错误状态的节点检测出错误时输出的错误标志,是由6个位的显性位组成。被动错误标志是处于被动错误状态的节点检测出错误时输出的错误标志,由6个位的隐性位组成(可以被其他节点的显性位所覆盖)。主动错误和被动错误后面会讲到,这里可以作为了解就行。
- 错误界定符:错误界定符由8个位的隐性位构成。
4、过载帧
过载帧是用于接收节点通知其尚未完成接收准备的帧。过载帧由过载标志和过载界定符构成。
- 过载标志:过载标志的构成与主动错误标志的构成相同。由6个位的显性位构成。
- 过载界定符:过载界定符的构成与错误界定符的构成相同。由8个位的隐性位构成。
5、帧间隔
帧间隔是用于分隔数据帧和遥控帧的帧。数据帧和遥控帧可通过插入帧间隔将本帧与前面的任何帧(数据帧、 遥控帧、错误帧、过载帧)分开。需要特别注意的是过载帧和错误帧前不能插入帧间隔。
- 间隔:3 个位的隐性位。
- 总线空闲:隐性电平,无长度限制(0亦可)。在这个状态下,可视为总线空闲,要发送的单元可开始访问总线。
- 延迟传送:8 个位的隐性位。只在处于被动错误状态的单元刚发送一个消息后的帧间隔中包含的段。
四、CAN错误处理机制
1、CAN的错误种类
CAN的错误种类有五种:位错误、填充错误、CRC错误、格式错误、ACK错误。
- 位错误:位错误是发送节点或接收节点发现输出的电平与总线电平(不含填充位)不一致时,所监测到的错误。只有在数据帧、遥控帧、错误帧、过载帧中才能监测出“位错误”。当前节点检测出错误后的下一位开始输出错误标志。
- 填充错误:当发送/接收节点监测到数据帧(帧起始到CRC序列)、遥控帧(CRC序列)连续6位都是相同的电平时,就会检测出“填充错误”。当前节点检测出错误后的下一位开始输出错误标志。
- CRC错误:当接收节点接收到的数据计算出的CRC结果与接收到的CRC序列不同时,就会监测出“CRC错误”。当前节点检测出错误后,将在ACK 界定符后的下一位开始输出错误标志。
- 格式错误:格式错误是当接收节点发现固定格式的位有问题时,就会监测到格式错误。比如监测到数据帧/遥控帧中的CRC界定符、ACK界定符和EOF(帧结束段)以及错误界定符、过载界定符不为隐性电平1时,CAN接收节点就会监测到格式错误。当前节点检测出错误后的下一位开始输出错误标志。
- ACK错误:CAN发送节点发现ACK槽是隐性电平1时,就会检测到ACK错误。当前节点检测出错误后的下一位开始输出错误标志。
当发送节点或者接收节点在检测到满足条件的错误时,就会输出错误帧来通报错误,也就是会输出错误帧。处于主动错误状态的单元输出的错误标志为主动错误标志;处于被动错误状态的单元输出的错误标志为被动错误标志。
发送单元发送完错误帧后,将再次发送数据帧或遥控帧。
2、CAN的错误状态(主动错误、被动错误、BusOff)
认识了CAN的错误种类,我们就需要了解CAN的错误状态了。CAN的错误状态分为以下三种:①主动错误(Error Active);②被动错误(Error Passive);③总线关闭(Bus Off)。
- 处于主动错误的节点可以参与总线通信,并且在检测到主动错误时,发送显性电平的主动错误标志(发送错误帧)。
- 处于被动错误的节点也可以参与总线通信,但是当此节点检测到错误时,它不能发送主动错误标志,而只能发送隐性电平的被动错误标志(发错误帧)。其次处于被动错误状态的节点在发送结束后不能马上开始下一次的发送。必须在下次发送之前,必须插入“延迟传送”(8个位的隐性位)的帧间隔。
- 处于总线关闭(Bus Off)的节点,不能参与总线通信(也就是不能往总线发送数据也不能接收总线上的数据)。
CAN节点如何进入主动错误状态、被动错误状态、总线关闭(Bus Off)状态?
其实官方为了约束错误状态,引入了两个量:发送错误计数器(TEC)和接收错误计数器(REC)。每个节点都有自己独立的发送错误计数器和接收错误计数器。CAN节点处于主动错误状态还是被动错误状态亦或是总线关闭状态(BusOff)取决于发送错误计数器的值和接收错误计数器的值。
发送错误计数器和接收错误计数器的值如何变化呢?
发送错误计数器和接收错误计数器值变化的范围如下图:
五、CAN的位时序
发送节点在非同步的情况下每秒发送的位数称为位速率(也就是我们常说的波特率),一个位可分为4个段,分别是同步段(SS)、传播时间段(PTS)、相位缓冲段1(PBS1)、相位缓冲段2(PBS2)。
1位分为4个段,每个段又由若干个Tq构成,这称为位时序。这些段由Time Quantum(Tq)的最小时间单位构成。1 个位由多少个Tq构成、每个段又由多少个Tq构成等,这些都是可设置的。通过设定相同的位时序,多个单元可同时采样,也可任意设定采样点,一般CAN的采用点位于PBS1之后。
CAN采样点计算
采样点的计算方式为:SamplePoint = (SS+PTS+PBS1)/(SS+PTS+PBS1+PBS2)
采样点如何实测,参照:
参考文献:
[1] CAN入门书(瑞萨)
[2] CAN Specification Version 2.0(Bosch)
[3] CAN Primer: Creating Your own Network(MDK)