前面我们介绍了CAN通信的物理层,它定义了通信的接口、信号的类型(高低电平)、如何采样(位时间)等内容。但是仅有物理层是不够的,比如假设接收到“0110”这样的数据,我们并不知道它代表的意义是什么。因此还需要对报文格式进行定义,这就是数据链路层的工作。
数据链路层对数据的组织形式进行定义,也就是所谓的“帧”。经典CAN和CAN-FD的数据链路层是不同的。本文先介绍经典CAN(以高速CAN为例)的数据链路层,下一篇文章介绍CAN-FD的数据链路层。
经典CAN的帧类别包括:数据帧、远程帧、错误帧和过载帧。
1、数据帧(data frame)
关于经典CAN的数据帧,我之前的曾写过一篇文章:
这里不再赘述,只是强调一些内容:
①经典CAN的数据帧分为七个不同的域,包括:帧起始、仲裁域、控制域、数据域、校验域、确认域和帧结束,如下图所示:
帧起始用来告诉总线数据传输的开始。仲裁域主要是标识符(CAN-ID),当不同的节点争夺总线控制权时,用来判决哪个节点可以使用总线。对于某个节点而言,标识符也用在其过滤机制中,用来选择自己感兴趣的数据和过滤掉不感兴趣的数据。控制域用来设置传输数据的长度。数据域存放实际传输的数据。校验域用来对数据进行循环冗余校验,确认域告诉发送方数据已经正确接收,帧结束用来告诉总线数据传输的结束。
②经典CAN的数据帧有两种类型:标准帧和扩展帧。标准帧出自CAN 2.0A标准的定义,扩展帧出自CAN 2.0B标准的定义。它们的区别是标识符(CAN-ID)的长度不同:标准帧最多支持11位标识符,扩展帧最多支持29位标识符;
③顾名思义,数据帧是用来传输数据的。经典CAN最多支持8字节的数据传输,无论标准帧还是扩展帧均是如此;
2、远程帧
一般情况下,CAN节点会通过数据帧主动向外发送数据,对其数据感兴趣的接收方就能收到数据。某些情况下,作为数据接收方,CAN节点也可以主动要求某个节点发送数据,这是通过远程帧完成的。换句话说,某个节点可以通过发送远程帧主动向另一个节点请求特定的数据。
远程帧与数据帧类似,也分为标准帧和扩展帧(这个好理解,因为其请求的节点的标识符可能是11位,也可能是29位),不过它没有数据域。
远程帧分为六个不同的域:帧起始、仲裁域、控制域、校验域、确认域和帧结束,如下图所示:
说明:
①与数据帧不同,其仲裁域的RTR位为“隐性电平”(数据帧的该位为显性电平),也就是逻辑“1”;
②控制域中的“DLC(Data Length Code)”是其请求的数据长度(另一节点发送的数据帧的长度);
③实际项目中远程帧使用的不多,在CAN-FD协议中已经取消了远程帧;
3、错误帧
如果CAN总线上的节点检测到错误,就会主动向总线发送错误帧,通知其它节点有错误发生。
错误帧由两部分组成:错误标志域和错误限定符域,如下图所示:
错误标志域:错误标志域是六位相同信号(显性或隐性,视其错误类型不同)。根据CAN协议的规定,正常情况下收到的连续相同信号的位数不会超过五个(见后文的填充错误),因此这里六位长度的错误标志域会引起总线上所有节点检测到错误并发送错误标志到总线,这些错误标志可能会有重叠的部分。比如某个节点发送了一个显性电平,但它进行回读时得到了一个隐性电平。于是它就发送了六个显性电平表示发现了错误。当它发送完毕后,其它节点读到了六个显性电平,显然也是错误的,于是其它节点也发送了错误标志(六个显性电平),于是就产生了一个12位的错误标志。如果某个节点是在中途就发现了错误(比如发送了三个位),则最终产生的错误标志的长度会小于12位(有重叠的部分);
错误限定符域:8位长度的隐性信号;
CAN节点可能检测到的错误包括:位错误、确认错误、填充错误、校验错误和格式错误。
①位错误:CAN节点向总线发送信号后会进行回读,如果读取的信号与发送的信号不同,则会产生一个位错误;
②确认错误:根据CAN协议的规定,当节点发送完一帧数据后,任何节点收到该数据都应该在发送一个显性信号到总线上进行应答(ACK)。如果发送节点没有在指定的时间内收到应答信号,则会产生确认错误;
③填充错误:CAN协议规定,节点发送数据帧或远程帧时,若其【校验域】前的数据存在连续五位是相同数值的情况,则发送五个相同电平后应填充一个相反极性的电平,再继续发送原数据。因此,正常情况下,接收方不会收到超过五个连续相同的电平信号。如果收到了超过五个连续相同的电平信号,则会产生填充错误(注意仅针对数据帧或远程帧的校验域之前部分这样处理);
④校验错误:接收节点在收到数据后会进行CRC校验,并与发送过来的CRC校验值(数据帧中的校验域)进行比较,如果不相同,则产生校验错误;
⑤格式错误:对于域中某些位是固定格式的帧,如果其格式不对,则产生格式错误;
每个CAN节点内部都有错误计数器(包括发送错误计数器和接收错误计数器),节点会根据错误的情况将自身至于:主动错误状态、被动错误状态或总线关闭状态。这三种状态满足一定条件会相互转换。
在实际编程应用中,我们很少处理错误帧,这些工作都是CAN控制器帮我们完成。
4、过载帧
过载帧用于通知CAN总线的所有节点目前总线处于过载情况,请暂缓发送数据。CAN节点在两种情况下都会发送过载帧:
①作为数据接收方,需要一段时间间歇(可能是数据太多处理不完);
②在总线间歇期间收到了一个显性位电平;
过载帧与错误帧类似,包括:过载标志域和过载限定符域,如下图所示:
过载标志域:由6位显性信号组成;
过载限定符域:由8位隐性信号组成;
过载标志是六个显性电平,总线上的其它节点读到会认为是错误,于是就会发送错误标志。过载标志和错误标志可能会有重叠的部分。
好了,关于经典CAN(2.0)数据链路层的帧格式就先介绍到这里,下一篇文章我们介绍CAN-FD的数据链路层。
下面是【CAN通信技术】的文章归档链接:
我的书《西门子S7-1200/1500 PLC SCL语言编程 ——从入门到精通》从硬件到软件,比较详细的介绍了SCL语言的编程,感兴趣的话可以扫描下面的二维码查看:
发表评论