一、CAN物理层
一个双节点CAN网络示意图如下,两颗120Ω终端电阻并联呈现总线电阻60Ω。
A、B两个节点的CAN收发器(Transceiver),只负责电平转换。当总线静默时,收发器内部的2.5V电源经15KΩ电阻把CAN-H和CAN-L都拉到2.5V,总线这个状态称之为隐性。当节点A想要驱动总线的时候(TX=0),它同时把内部的上下两个MOS管导通,整个网络的电流流向:节点A的5V电源经二极管、24Ω、两颗终端电阻并联、24Ω、二极管回到节点A的地,总线这个状态称之为显性。CAN总线上的电压实际上就是终端电阻的分压。从节点B来看,CAN-H就变成3.5V,CAN-L变成1.5V,拉出了总线 H - L = 2V 的差分电压,大于0.7V的判断阈值,节点B就认为收到了一个显性(RX=0)。
上图是TJA1050CAN收发器的Block Diagram,CAN收发器的CANH和CANL信号采用差分电平,具有很强的抗击共模噪声的能力。当两个晶体管都关断时,CANH和CANL上电压相同,都为 0.5VCC(CANH = CANL = 2.5V),此时为逻辑“1”(隐性状态Recessive) ;而当两个晶体管都打开时,CANH 和 CANL 上即存在一定的压差,且压差与负载电阻值相关,ISO 11898-2 要求此时 CANH 和 CANL 压差在 2V左右,此时为逻辑“0”(显性状态Dominant)。
二、CAN数据链路层
CAN总线定义四种帧类型,分别为数据帧、远程帧、错误帧和过载帧。
(一)、CAN数据帧
CAN数据帧结构上由7个段组成:帧起始、仲裁段、控制段、数据段、CRC段、ACK段和帧结束,其中根据仲裁段ID码长度的不同,分为标准帧(CAN2.0A)和扩展帧(CAN2.0B)。
1、CAN帧的格式
标准格式的ID有11个位,从ID28到ID18被依次发送,禁止高7位都为隐性(禁止设定:ID=1111111XXXX)。扩展格式的 ID有29个位,基本ID从ID28到ID18,扩展ID由ID17到ID0 表示,基本ID和标准格式的ID相同。
CAN数据帧各字段定义及长度分别为:
- SOF:表示数据帧开始;(1 bit)
- Identifier:标准格式11 bit,扩展格式29 bit包括Base Identifier(11 bit)和Extended Identifier(18 bit),该区段标识数据帧的优先级,数值越小,优先级越高;
- RTR:远程传输请求位,0时表示为数据帧,1表示为远程帧,也就是说RTR=1时,消息帧的Data Field为空;(1 bit)
- IDE:标识符扩展位,0时表示为标准格式,1表示为扩展格式;(1 bit)
- DLC:数据长度代码,08表示数据长度为08 Byte;(4 bit)
- Data Field:数据域,MSB优先传输;(0~8 Byte)
- CRC Sequence:校验域,校验算法G(x) = x15 + x14 + x10 + x8 + x7 + x4 + x3 + 1;(15 bit)
- DEL:校验域和应答域的隐性界定符(Delimiter,DEL);(1 bit)
- ACK:应答(ACK Slot),确认数据是否正常接收,所谓正常接收是指不含填充错误、格式错误、 CRC 错误。发送节点将此位为1,接收节点正常接收数据后将此位置为0;(1 bit)
- DEL:ACK界定符(Delimiter,DEL),同样为隐性位,用于隔开;(1 bit)
- SRR:替代远程请求位RTR,在扩展格式中占位用,必须为1;(1 bit)
- EOF:连续7个隐性位(1)表示帧结束;(7 bit)
- ITM:帧间空间,Intermission (ITM),又称Interframe Space (IFS),连续3个隐性位,但它不属于数据帧。帧间空间是用于将数据帧和远程帧与前面的帧分离开来的帧。数据帧和远程帧可通过插入帧间空间将本帧与前面的任何帧(数据帧、遥控帧、错误帧、过载帧)分开。过载帧和错误帧前不能插入帧间空间。
2、报文接收过滤
CAN控制器大多具有根据ID过滤报文的功能,即只接收某些ID的报文。节点对接收到的报文进行过滤:比较消息ID与选择器(Accepter)中和接受过滤相关位是否相同。如果相同,接收;如果不相同,则过滤。
消息在CAN总线上是广播式的,但并不是所有节点都会接收总线上所有消息。节点通过控制器中过滤码(Filter Code)和掩码(Mask Code),再检验总线上消息的标识符(29位),来判断是否接收该消息(Message Filtering)。
对于掩码,“1”表示该位与本节点相关,“0”表示该位与本节点不相关。
No. | 过滤码 | 掩码 | 备注 |
1 | 0x00001060 | 0x1FFFFFFF | 仅接收标识符为00001060的帧 |
2 | 0x00001060 | 0x1FFFFFF0 | 接收消息标识符为00001060到 0000106F的帧 |
3 | 0x00001060 | 0x1FFFFFF8 | 接收消息标识符为00001060到 00001067的帧 |
4 | 0x00001060 | 0x00000000 | 节点接收总线上所有消息 |
3、位填充
CAN总线使用到的是非归零编码(NRZ),NRZ编码的优点是效率高,但却不易区分哪里是bit开始,哪里是bit结束。因此为确保在同步通信过程中有足够的电平跳变,规范中应用到位填充机制,即在每连续5个相同电平后插入 1个反相电平,接收节点在收到消息后自动将填充位删除。在帧内除了CRC界定符、ACK域和EOF外,其余部分均应用到位填充机制。在应用到位填充的域,检测到连续 6个显性位或隐性位均视为报错。检测到错误后,节点将发出主动错误标志。主动错误标志为连续6个显性位,它是不符合位填充规则的,因此检测到该电平的所有节点都会报错。
位填充意味着实际传输的数据帧长度可能更长,下图示例位填充前后的数据帧的变化,紫色位是位填充增加的位,接收节点收到消息后会自动删除这些位。
如上图,数据是0x01,二进制0000 0001,发送节点发到0000 0的时候发送节点会先插一个1,再发后续的001,成为0000 01001,共9bit长度,接收节点也会在第5bit的0之后预期一个无效的1,解码时抠掉。如果数据是0000 0100,第六位自带1,发送节点发到00000的时候也会先插一个1,再发后续的100,成为0000 01100,共9bit长度。
标准格式CAN波形图如下,其中绿色的“1”为位填充。
4、仲裁机制
CAN-bus并没有规定节点的优先级,而是通过标识符ID来进行优先级的仲裁。
CAN总线的信号电平具有线与特性,即显性电平(0)总是会掩盖隐性电平(1)。如果不同节点同时发送显性和隐性电平,总线上表现出显性电平(0),只有在总线上所有节点发送的都是隐性电平(1)时,总线才表现为隐性。
CAN控制器在发送数据的同时会监测总线上的电平是否与发送数据对应的电平相同,如果不相同,则停止发送,进入只听模式。
如果多个节点同时往总线上发送消息,总线的使用权是通过消息帧标识符的逐位仲裁机制决定的,在仲裁过程中消息是不会丢失的。这里的不会丢失的意思是指仲裁完成后,获得总线控制权的消息内容没有被仲裁过程篡改,将继续在总线上发送没有传输完的消息。
在CAN总线上,标识符值越小,消息的优先级越高。标识符全零的消息,由于它将总线电平保持在显性的时间最长,因此优先级最高。
5、ACK应答机制
ACK在发送节点发送时,为隐性位。当一个接收节点接收的帧起始到CRC段之间的内容没有发生错误时,它将在ACK段发送一个显性电平。发送节点根据此显性电平判断发送成功。下图绿色的CAN TX信号,是接收节点在判断接收没有错误后发送的ACK应答显性电平。
(二)、CAN错误帧
CAN-bus错误类型:
当出现以上任一种错误类型时,发送或接收节点将发送错误帧。错误帧由错误标志 + 错误界定符组成。错误标识分为主动错误标识和被动错误标识。
发送节点发送了0或1的时候,会回读确认总线是否和自己的发送相符,比如在仲裁段抢优先级失败就会等下一帧再发;如果发到了数据段,按理说此时总线应该只有自己,如果突然发现回读的0/1与自己发的不同,比如受到了干扰,发送节点就会输出“主动错误标志”——连续6bit显性0,来主动抛弃后续报文,同时让接收节点知道这一帧有误。
接收节点收到第6bit显性0的时候,因违背逢五补一的位填充规则,也会往总线上输出“主动错误标志”,所以会在总线上看到连续12bit的显性0,前6个来自发送节点,后6个来自接收节点。
参考资料:
一文读懂CAN系统架构和帧结构 - 知乎
升维打击!用示波器排查CAN的各种错误帧
以上资料及图片部分来源于网络,仅供个人学习用。如有侵权,请联系删除。