之前学习了Modbus协议的内容,后面几周晚上学习下Can总线。这几天晚上一直在看CanOpen协议源码,现在开始整理笔记,虽然网上有很多大牛写过,我还是自己记录下,这样印象才深刻。
文章目录
1.Can总线电平介绍
Can总线为差分信合,抗干扰能力强。空闲时Can_H和Can_L的电平约为2.5V。下图是我在调试stm32 Can总线测量的波形,上面是Can_L,**下面是Can_H。**当时测量时给can收发器上的电源不到5V,所以看到前面和后面稳定电平只有2V。
-
显性和隐性电平
在空闲状态Can总线电平为2.5V左右,此时总线表现的为隐形状态。当发送数据时Can_H会上升至少1V左右,而Can_L会下降1V左右,此时总线表现为显性状态。
[1]总线空闲时,总线表现为隐形电平(高电平)
[2]CanH上升Can_L下降,总线为隐形电平(低电平) -
为什么显性表现为低电平而隐性表现为高电平
主要是Can总线执行的是 “线与” 操作。如下所示,某一时刻A发送0数据,使得总线为显性0状态,此时如果B在发送1时,检测到总线电平为0,所以1&0还是0,其实这里就是仲裁的原理了。
2.Can总线何时是空闲的
当总线连续表现为11个位的隐形电平(高电平),则总线为空闲状态。但是Can总线不是说5个相同位后就会有一个反转位码,那是发生在发送数据时。总线空闲时没有发送数据,发送数据时不会出现这么多隐性位。
3.Can总线的标准帧和扩展帧结构
下图为Can总线帧格式,目前有两种格式,标准帧和扩展帧。差异主要体现在标识符。
图片引用自:(https://www.cnblogs.com/isAndyWu/p/10298670.html)这篇博文写的也不错。
-
SOF(Start of Frame):
帧起始位由一个显性位启动(0),因为总线空闲时表现为高电平,那么此时发送一个显性0。收发器很快能侦测到有帧开始发送了。 -
仲裁域(Arbitration Field)
仲裁域用来判断帧的优先级,优先级高的帧能得到总线使用权,其它仲裁失败的设备自动转为接收状态,待总线空闲时在发送数据。标准帧和扩展帧最大的区别主要体现在ID长度,区别如下:-
标准帧
【1】.标准帧的ID有11位,这11位也是可以划分功能的。
【2】.RTR(Remote Transmit Request):这个为远程传输请求标志位,当节点需要请求其它节点的数据时,会发送远程帧请求数据(置1)。发送数据帧时此位置0. -
扩展帧
【1】.扩展帧的标识符有29位,包括基本的11位ID和18位扩展ID。
基本的11位ID决定扩展帧的基本优先级(这会和标准帧进行仲裁)。
【2】.SRR(Substitute Remote Request):此位为隐性位,这一位替代了原来的RTR位。如果其它设备也发送标准数据帧且ID和扩展帧前11位一样,那么标准帧优先发送。标准帧中的IDE为显性位,而扩展帧中的IDE为隐性位,所以标准帧的优先级高于扩展帧。
-
-
控制域(Control Field)
控制域有6个bit的数据IDE/r1、r0、DLC3、DLC2、DLC1、DLC0上面能够看到,DLC(data length code) 有4个bit,说明最大能发送16个biit,但是实际中最大只能有8个byte,64Bit- 标准帧
标准帧的ide/r1,r0其实是保留位,为显性位(0) - 扩展帧
IDE(Identifier Extension):扩展标识符,当发送的是扩展帧时,此位为隐性电平。
- 标准帧
-
数据域(Data Field)
数据域最大可以保存64bit,8个字节。 -
CRC域(CRC Field)
包含15bit的CRC 序列和 CRC 界定符,CRC校验数据可以由硬件或者软件生成,界定符为“隐性”位(高电平) 。 -
ACK域(ACK Field)
应答域为2个bit,当发送站,发送完一帧后,它会往总线上发送2个位的隐性位,当主机接收到有效数据后,会在bit1保持期间,向总线发送一个显性位,这样发送者就能检测到有设备应答了。剩下的bit0,仍然是隐性位。bit1 bit0 -
EOF(End of Frame)
帧尾由7个连续的隐性位组成
4Can总线帧类型
4.1 数据帧
设备发送请求数据时,发送的即为数据帧。其帧结构前面已经记录过
4.2 远程帧
当设备需要请求其它数据时,即会发送远程帧。收到请求的设备,就会把数据发送过来。
4.3 错误帧
错误帧这块东西有点多,不过总结下来,就不难理解了。
(1)错误情景分下面几类
- CRC错误:这个好理解,接收节点接收数据检验时,发现接收的CRC和计算得到的CRC不同。
- 应答错误
发送节点发送第一个bit1的显性位时,没有设备将总线拉低。没有接收到应答信号。 - 位发送错误
发送数据期间,当发送数据与总线的电平不同时,发生此错误。比如发送数据时,某一时刻发送1,但是总线读过来的是0,就会发生错误。 - 位填充错误
在发送数据期间,每连续发送5个相同的位时,都会自动发送一个反转位防止出错。没有就会报错了。 - 格式错误
帧格式不在那4种报文格式之内,
(2)错误帧类型
该类型由错误标志
和错误分隔符
上图和下图引用自瑞萨的《Can入门书》,其中TEC和REC不是发送和接收帧的数量,可以理解成错误的严重性。有几条评判标准,每满足一项,REC或者TEC都会累加一定值。
-
主动错误状态:当0<TEC<127或者0<REC<127时此设备处于主动错误状态,主动错误标志符为6个显性电平。
-
被动错误状态:128<TEC<255或者128<REC<255时此设备处于被动错误。被动错误标志符为6个高电平
当设备检测到发送或接收错误时,就会发送主动错误标志符(一开始是主动)。错误标志符会影响接收节点接收帧,进而从站检测到错误(CRC),然后那些处于主动状态的节点同样会往总线发送6个隐性位。
举个例子来说:
- 当首个处于主动错误状态的节点t1时刻开始发送错误标志符时,同时所有节点都侦测到错误且都处于主动错误状态,那么此时会呈现6个显性和8个隐性(总线线与后波形一致)。
- 当t1-1首个设备检测错误,此时首个设备开始发送错误标志符。 并发送被动错误标志符(6个隐性),此时被动错误标志会被主动标志符覆盖。
- 在t1-1时刻,首个设备检测到错误,开始向总线发送错误标识符。加入此时传输的数据恰好是0x00,此时发送前五个0的时候,接收设备仍然以为在发送数据。当t-2时刻就会发生位填充错误,其它设备也会发送错误标志符,紧接着发送8个隐性位。
下面是stm32的Can帧格式,可以看到错误帧最多能有12bit的显性标志符。
4.4 过载帧
用于接收单元通知发送数据的单元,它还没有准备好接收帧。由过载标志和过载分隔符构成。
-
过载标志: 由6个显行位组成(6个0)
-
过载分隔符: 8个隐性位构成(6个1)
上面能够看到过载帧和主动错误帧标志符很类似。这样的话他们该怎么区分呢。从下图中能够看到过载帧前面可以是EOF、错误帧分隔符、过载帧分隔符。而错误帧前面是没有这个约束的。
5.Can总线仲裁机制
Can总线仲裁由帧中的仲裁域判断,在发送数据期间发送设备对发送的数据位与总线的电平进行比较。如果电平相同则继续发送后续bit位。如果不同且发送的位数据为隐性,而总线电平为显性,那么仲裁就失败了,退出发送状态了。其实也就说 消息的帧ID约小就先发送。以标准帧为举个例子吧。
-
举例说明
加入某一个时刻有2个节点Node-A和Node-B分别发送ID为0x0a和0x11的数据。数据 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0x0a 0 0 0 0 1 0 1 0 0x11 0 0 0 1 0 0 0 1 总线发送数据线发送高位,可以看到bit7~bit5他们都是一样,难分胜负。到了bit4的时候,Node-A就胜出了。因为进行线与操作后,bit4和总线电平为显性。
-
当具有相同识别符的数据帧和远程帧,数据帧优先于远程帧
-
当扩展帧前11位ID和标准帧ID一样的话,标准帧优先级比扩展帧优先级高。