看过我之前的文章就知道,正点原子下的linux中CAN总线并没有讲的很明白,都是系统自带的!
这里我找到江科大学长的can总线的讲解视频!
CAN总线入门教程-全面细致 面包板教学 多机通信_哔哩哔哩_bilibili
在这里我也会一步一步讲解CAN总线的协议编写流程!
1、can 简介
我们以STM32F103C8T6为例实现基本的驱动!
下面的主流通信协议在之前的文章中也讲过!
1.1、can硬件电路
can总线可以看作是串口UART和I2C通信的结合体,不过尤为重要的是,can通信的TX和RX不需要交叉相连!
其中右边的电路的2.2k欧的电阻是悬空的!
1.2、can的电平标准
可以看到逻辑电平和差分电平!
按直觉来说,1是显性电平和0是隐形电平。
但是差分信号是相反的,1是隐形电平,0是显性电平!
为了观察现象方便和学习CAN总线协议,我们后面用逻辑电平来理解!
1,3、can收发器-TJA1050(高速can)
看到上面这个图片,一共有8个引脚。VCC需要5V的供电!
TX与RX与MCU相连(也就是CAN控制器),CANH与CANL与CAN总线相连!
Vref是参考电压输出!可以不用连接!
S:选择高速模式还是静默模式。
可以分析一下这个电路!
当CANH与CANL有电压差的时候,此时是显性电平0,就会在RECEIVER的地方输出1;当CANH与CANL没有电压差的时候,此时是隐性电平1,就会在RECEIVER的地方输出0;
输出的0和1,就会通过左边的场效应管来驱动到RXD引脚,场效应管可以当做电子开关,当RECEIVER输出为1时,也就是上管断开,下管导通,会使GND导通,即输出0;当RECEIVER输出为0时,也就是上管导通,下管断开,会使VCC导通,即输出1;
我们再来分析一下TXD的作用!
当TXD为1时,会使得上下两个场效应管断开!
相当于不对CAN总线有任何的操作!即保持0电压差!在收紧状态下,呈现隐形电平1。
当TXD给0时,上下两个场效应管都导通!
可以看作上面的场效应管把CANH拉高!下面的场效应管把CANL拉低!这个时候就有电压差了!就是显性电平0。
这样我们就可以总结;当发送的时候,TXD发1,隐形电平1,TXD发0,显性电平0;当接收的时候,若为隐形电平1,则RXD为1,若为显性电平0,则RXD为0。这样我们就可以按照这个逻辑实现CAN总线的多主机通信协议!
如果TXD悬空了!则上拉的VCC电源会保持默认输入1的状态,旁边还有TXD显性超时计时器,作用是。如果TXD输入操作异常,始终输入显性电平0,则CAN总线始终保持有电压差的状态,则这样会导致CAN总线瘫痪,并且没有设备可以阻止这一个现象!那么TXD显性超时计时器就是当发生上面所讲的情况,就会等一段时间后,收发器会自动释放CAN总线,使得为隐形电平1,防止CAN总线瘫痪!
接下来我们分析S引脚!
S引脚下面有个下拉的GND,如果S引脚悬空,则默认输入为低电平!
旁边的是温度保护,如果温度异常,就会控制驱动器,切断输出,以免干扰CAN总线!
1.4、CAN物理特性
2、帧格式
2.1、数据帧格式
D/R:这段时序根据你要发送的数据的不同,可以选择发D(显性0)和选择发R(隐形1);
R:表示发隐形1;
D:表示发显性0;
白色是发隐形电平1,灰色是发显性电平0。
白色和灰色各占一半是应答位特有的。在应答位的时候,发送方必须发隐形电平1,接收方必须发显性0。这个的意思就是发送方释放总线和接收方拉开总线!
图上的数字表示该时序所占的位数!
帧起始:可以看到是帧开始位灰色从显性电平0,也就是逻辑0开始的,有电压差,表示要开始发送了。
仲裁段:仲裁段是11位报文ID,报文ID还区分优先级,当多个设备进行操作时,一般会根据ID的大小来判断优先级!RTR占一位,在数据帧里必须是显性电平0,RTR的意思是远程请求标志位。报文ID+RTR就是仲裁段,仲裁主要靠报文ID,RTR是用于相同ID的数据帧和遥控帧,数据帧的优先级大于遥控帧,数据帧和遥控帧的报文ID是可以相同的,他这里和I2C的特别相似,7位从机地址+1位读写位,那么这里数据帧的RTR就是写入,遥控帧的RTR就是读取。上面的图片的RTR是灰色的隐形电平0那就是数据帧的标识!区分遥控帧1
控制段:首先是IDE,是ID扩展标志位,用于区分标准格式还是扩展格式,标准格式为显性电平0,扩展格式为隐形电平1,可以看到图片中有标准格式和扩展格式的区分!其次为r0, 必须为显性0看,r0是保留位,保留位是以后用的着,DLC是数据段长度,比如看图片DLC的位数为4,必须为4,因为CAN总线的发送一帧数据为1~8个字节,一个字节是8位2进制数据,最多是8*8
,如果DLC为0001,则发送一个字节;若DLC为1000,则数据段是发送8个字节,也就是64个2进制数据。所以可以看到图片当中是0到64。
数据段:这里是0~64位。数据段要给8的倍数,具体给多少要看DLC的配置。
CRC段:这里有15位,CRC是一种高效的校验的算法,他会对前面所有的数据位进行验算。计算得到的校验码,附在这后面。接收方得到数据和校验码之后,也会进行CRC校验看看计算的校验码是否一致,以判断传输是否传输有错误!
CRC界定符:1位,必须为隐形电平1。
ACK段:ACK槽和ACK界定符,都是1位,ACK槽的作用就是应答,发送方发出一帧数据,到底有没有设备收到。当发送方在应答位,也就是ACK槽处,会释放CAN总线,隐形电平,如果接收方接收到了数据,接收方就会在这个ACK槽进行应答,也就是显性电平0,拉开总线。发送方释放总线后,会在ACK槽读取总线状态。ACK界定符和CPC界定符一起帮助ACK槽构成应答协议,适合这种特有的通信协议。这里有两个注意事项,第一个,可以允许多个接收方共同拉开总线,因为一个报文消息,可以被多个设备同时接收,多个设备可以在这里同时拉开。第二个:并不是发送方把一段波形完整的发出去,然后再接收方应答的。而是,发送方和接收方共同完成一整个波形。发送方每发出一位,接收方就立刻收到这一位了,所以在这条时序的最后,整个数据帧还没有结束,接收方其实已经收完了。所以当在CRC界定符+发送隐形电平+ACK界定符中间就可以让接收方应答了,因为发送方在CRC界定符+发送隐形电平+ACK界定符全是隐形电平。
可以看到下面这幅图片!
可以看到绿色的就是接收方拉开的。
也就是说应答是夹在发送过程当中的!
帧结束:应答之后,发送方会发7个隐形电平1,作为EOF,整个数据帧结束。
扩展格式:因为标准格式的11位ID不够用了,需要加一些,扩展格式也要考虑标准格式的兼容;首先,11位ID仍然保持不变,后面再加18位ID;SRR:代替RTR的位,扩展格式的RTR已经放在后面了,RTR必须放在ID后面,SRR这里是没有用的,所以给隐形电平1,;IDE:用于区分标准格式还是扩展格式,标准格式为显性电平0,扩展格式为隐形电平1;后面就是RTR了,之后的就跟标准格式差不多了!这样就是实现了扩展ID。
2.2、数据帧各部分用途简介
2.3、数据帧的发展历史
2.4、遥控帧格式
可以明显看出遥控帧和数据帧的区别!
遥控帧的RTR是1,数据帧的RTR是0,而且遥控帧没有数据段!
如果有设备需要的话,首先接收方会发出一个遥控帧,遥控帧会包含报文ID,遥控帧也是广播式的,每个设备都能收到遥控帧,如果其中有个设备有这个ID的数据,那么这个设备就会把数据帧通过广播出来,然后真正需要的接收方就会收到数据。(适合使用频率低的数据传输)
!:如果使用频率高,这种遥控帧请求式就不合适了!
因为请求式产生的遥控帧本身也在占用总线资源,所以使用高频率的数据的时候,还是直接用广播式的方法传输数据帧。
一次完整的数据传输:
需要遥控帧和数据帧配合!
2.5、错误帧
错误分为主动错误和被动错误。
设备默认为主动错误。
处于主动错误状态的设备,检测出错误的时候,会连续发6个显性位。这样必然会造成破坏正常数据的传输,其他设备检测到错误标志时,就会抛弃这个数据,主动错误产生太频繁了,说明这个设备不可靠,设备就会处于被动错误的状态!
==处于被动错误的状态的设备,==检测出错误的时候,会连续发6个隐形位,发6个1,也就是不去碰总线,就不会破坏总线别人发的数据,但是会破坏自己的数据。
0~6是0到6位的延长时间,一个设备发出的错误标志,可能会引发其他设备连带产生的错误标志,
多个设备叠加起来的错误标志不止6位,所以加了0~6,
2.6、过载帧
2.7、帧间隔
下图这个分为主动错误状态和被动错误状态!
2.8、位填充
2.9、分析波形实例
可以看到标准数据帧的4位DLC是00101,本应该是0001的,但是要位填充补了1。
CRC的内容有CAN收发器自动生成,不用我们管!
CRC校验时,不需要填充位,所以会自动剔除填充位。只关心真正的数据。
3、接收方数据采样
3.1、接收方数据采样遇到的问题
3.2、位时序
3.3、硬同步
3.4、再同步
3.5、波特率计算
4、仲裁
4.1、先占先得
4.2、非破坏性仲裁
4.3、非破坏性仲裁过程
4.4、数据帧和遥控帧的优先级
4.5、标准格式和扩展格式的优先级
5、错误处理
5.1、错误帧
5.2、错误状态
5.3、错误计数器
5.4、主动错误帧和被动错误帧波形实例