赞
踩
目录
CAN总线可以实现多个主控互相通信,它的应用场景是超过两个的单片机主控系统之间进行通信,用两根线的CAN总线将每个主控串起来,这样就可以实现任意的数据传输了。
CAN收发器主要实现电平转换、输出驱动和输入采样几个功能。
电压差为0V时表示逻辑1(隐性电平)
电压差为2V时表示逻辑0(显性电平)
电压差为-1.5V时表示逻辑1(隐性电平)
电压差为3V时表示逻辑0(显性电平)
以TJA1050(高速CAN)为例
数据帧的用途是发送设备主动发送数据帧,属于广播式通信方式。有标准格式和拓展格式两种,CAN总线刚制定时只有标准格式,拓展格式是后来新增的,拓展格式增加了ID位数能承载更多类型的ID。
图例的灰色部分表示显性电平,也就是灰色部分必须发显性电平0,图上紫色部分D/R表示这段时序根据要发送的数据的不同可以选择发D也可以选择发R,白色部分表示必须是隐形电平1。白色和灰色各占一半是应答位特有的,在这一位发送方必须发送隐形1,接收方必须发显性0,也就是发送方释放总线,接收方拉开总线,表示接收方对发送方的应答。
在发送数据帧之前总线必须处于空闲状态,空闲状态时总线是隐形电平,随后数据帧开始,数据帧第一位图上线画的低电平,颜色是灰色,表示此位必须是显性电平0,它的意思是SOF,帧起始。与串口波形的起始位一样帧起始的作用是“打破宁静”,因为空闲是隐形1所有设备都不去碰总线,那你要开始发数据帧第一位就必须得张开总线发送显性0。
一位帧起始之后,首先发送的是报文ID,标准格式是11位,如果你想发报文ID是101 0101 0101那这一段时序就是:隐显隐 显隐显隐 显隐显隐,报文ID可以表示后面数据的功能,因为总线上各种报文信息都有,如果没有ID加以区分那肯定就搞混了。同时报文ID还用于区分优先级,当多个设备同时发送时,根据仲裁规则(后文再详细介绍)ID小的报文优先发送,ID大的报文等待下一次总线空闲再重新发送,不同功能的数据帧其ID都不同。
报文ID后紧跟着的是RTR,占据1位,在数据帧里必须为显性0,RTR的意思是远程请求标志位,用于区分数据帧还是遥控帧,数据帧必须为显性0,遥控帧必须为隐形1。报文ID+RTR位可以称为仲裁段,仲裁主要靠ID来实现,RTR也加入进来的目的是相同ID的数据帧和遥控帧,数据帧的优先级大于遥控帧。
之后进入控制段,控制段首先是IDE,意思是ID拓展标志位,用于区分标准格式还是拓展格式,标准格式固定为显性0,拓展格式固定为隐形1。之后下一位是r0,必须为显性0,r0意思是保留位,目前还没有用到。后面四位是DLC,意思是表示数据段的长度,CAN总线一帧数据可以有1~8个字节有效载荷,并且可以灵活指定,就靠这个DLC指定,如果想发一个字节DLC就给0001,如果想发8个字节,DLC就给1000,DLC要配合后面数据段使用。
数据段就是有效载荷的数据了,根据DLC的指定,数据段可以有多个字节,DLC指定几个字节数据段就发几个字节。数据段长度是0~64位,最大64位即8个字节,这里位数是8的倍数。
数据段之后是CRC段,有15位,CRC是高效的校验算法。从SOF到Data这些数据位计算得到的校验码附在这后面,接收方收到数据和校验码也会调用CRC算法进行计算,CRC算法不细讲了。
下一个是CRC界定符,1位,必须是隐形电平,之后就是ACK段,里面有ACK槽和ACK界定符,都是1位,ACK槽的作用就是应答,发送方发送一帧数据到底有没有设备接收到呢就靠ACK位来实现,这里的应答设计和I2C的应答异曲同工,它的基本思想就是当发送方发完一帧数据的主要内容后在应答这一位时发送方释放总线,总线回归默认状态隐形1,如果接收方收到数据了它就会在ACK槽这一位主动出击把总线再拉开时总线呈现显性0的状态,发送方释放总线后在ACK槽会读取总线状态,如果发送方读取为显性0那就是数据被接收了,如果发送方读取为隐形1就说明发送失败发送方可以配置自动重发。可以看到在ACK槽这一位操作总线的权力是有一个短暂的交接的,前面所有波形都只有发送方有权操作总线,在ACK槽这一位变为接收方操作总线,为了给权力交接流出时间,ACK槽前后就要留两个界定符,在CRC界定符时发送方必须发隐形1,除了做一个分隔另一个作用就是在ACK槽之前发送方必须释放总线,发送隐形1就是释放总线,之后在ACK槽的时间点接收方会拉开总线,ACK槽接收后接收方不能一直拉着不放所以在ACK界定符时接收方必须及时释放总线交出控制权。
这里有两个注意事项,第一个是ACK槽时可以允许多个接收方共同拉开总线,因为一个报文消息可以被多个设备同时接收,所以多个设备可以在这里同时拉开,多个设备同时操作总线输出显性0是没问题的。第二个是,我没要知道并不是发送方把一段波形完整发出去然后在接收应答的,而是发送方和接收方共同完成一整个波形,发送方每发出一位,接收方就立刻接收到这一位了,所以在这条时序的最后整个数据帧还没结束接收方其实已经收完了,也就是应答位夹在发送过程之中。
最后应答位结束发送方再发7个隐形1,作为EOF帧结束,与串口波形里的停止位是一个意思。
看完了标准格式再看一下拓展格式,拓展格式出现的原因是标准格式的11位ID不够用了,需要加一些,并且拓展格式必须要考虑对标准格式的兼容。首先前面的11位ID仍然保持不变,后面另外再额外加上18位ID,那么中间还夹着两位一个是SRR意思是替代RTR位,标准格式这一位是RTR,后面学仲裁会知道。仲裁是先比较ID再比较RTR,所以RTR必须在所有ID位的后面,图上也用箭头指示了拓展格式中RTR位已经挪到后面,那原来属于RTR的位置就空出来了,这一位虽然空出来了但是也不能做别的用途因为同样是为了保证仲裁规则中标准格式优先级高于拓展格式的设计,这一位SRR虽然没用但是必须给隐形电平1。然后后面IDE这一位就是拓展格式标志位了,标准格式中IDE为显性0,拓展格式中IDE为隐形1。最后ID结束后是RTR。
数据帧各部分用途总结:
遥控帧用途是接收设备主动请求数据,与数据帧非常类似,只是没有数据段有效载荷这部分。目前我们了解到CAN总线的数据主要靠发送方自觉广播出来,一般发送方会定一个周期定时广播自己的数据,但如果发送方没有及时发送数据或者这个数据使用频率太低了,广播太频繁大家都用不着浪费总线资源,广播太慢了偶尔用的话又不能及时拿到,这样我们就可以规定发送方就不用主动广播这个数据了,而是如果有设备需要的话首先接收方发出一个遥控帧,遥控帧包含报文ID,其实遥控帧也是广播出来的,每个设备都能收到遥控帧,然后如果其中某个设备有这个ID的数据它就会再通过数据帧广播出来,这样接收方就能及时获取这个数据了,所以可以看出遥控帧实现请求式数据传输也需要数据帧配合,请求式传输每传输一次数据,都需要一来一回两个过程,适合那种使用频率低但偶尔又需要集中用几次的数。
遥控帧和数据帧通过RTR进行区分,数据帧RTR是显性0,遥控帧RTR是隐形1,当接收方收到RTR是隐形1,后续就按照遥控帧的格式解析,遥控帧的DLC之后没有数据段直接跟着就是CRC校验码,遥控帧ID代表要请求的数据,响应请求的一方通过相同ID的数据帧反馈数据,当请求和反馈数据同时发生时,数据帧拥有更高的优先级。
初学了解即可。错误帧用途是某个设备检测出错误时向其他设备通知错误,当某个设备发现总线上的波形不对,产生错误,它就会发出错误帧,错误帧可以叠加在数据帧上,并且可以破坏数据帧数据,意思就是我发现这一帧数据有错,现在我破坏了这个数据大家都不要用了,是一种错误处理机制。
错误分为主动错误和被动错误,设备默认处于主动错误状态,处于主动错误状态的设备检测出错误时会连续发6个显性位,发显性位就是拉开总线,总线只要有一个设备拉开了就必然处于显性状态,即0和1相遇总线总是处于0状态,这是线与特性,所以主动错误标志的6个显性位必然会破坏正常传输的数据,其他设备检测到错误标志就会抛弃这个数据。主动错误产生太频繁说明这个设备不太可靠,设备就会进入被动错误状态,处于被动错误状态的设备检测出错误时会连续发6个隐形位,发送隐形位就是不去碰总线,不破坏总线别人发的数据,但是会破坏自己发的数据,自己的数据有问题自己破坏掉。发完错误标志后再发8个隐形1,作为错误界定符。0~6位的延长时间是因为一个设备发出的错误标志可能会引发其他设备连带产生错误标志位,多个设备的错误标志叠加起来这个标志位的长度可能就不止6位了所以后面这里画的是错误标志可能会延长0~6位的时间。
初学了解即可。用途是接收设备通知其尚未做好接收准备,其帧格式和错误帧类似,只是过载帧不是在错误帧的时候产生,而是发送方发太快接收方处理不了时由接收方产生。发过载帧将数据破坏掉发送方发不出去就会重试,在这个破坏和重试的过程中发送数据就被延误了,同时也间接告诉发送方,接收方收不了。
初学了解即可。
知道连续发送数据帧时其中间会有一小段间隔就好。帧间隔也分主动错误状态和被动错误状态,主动错误状态帧间隔是3位,被动错误状态帧间隔是3位另外加8位延迟传输。
为防止数据波形长时间不变化,引入位填充。
挂载在CAN总线上的所有设备初始都默认为接收方,当某一个设备想要广播自己的数据时,它就会主动出击变为发送方,拉开或释放总线产生一段波形。那这个发送方产生波形后其他所有接收方该如何准确地采样得到每一个数据位是1还是0呢?
Tq是程序中自己指定的,比如可以确定一个Tq=0.5us,之后一位包含的四个段,SS段固定为1Tq,PTS段可以由自己指定配置为1~8Tq,PBS1段也是自己指定配置为1~8Tq,PBS2段自己指定配置为2~8Tq,除了SS段固定为1Tq其他的可以由自己在一个范围内指定。指定好之后在一位中SS、PTS、PBS1、PBS2就会依次排列。SS段意为同步段,如果数据跳变沿正好出现在SS段那就说明当前设备与波形达成同步,如果数据跳变沿不在SS段那就要调整当前设备的位时序使跳变沿正好出现在同步段。PTS意为传播时间段,作业在手册里是这样说的:PTS用于吸收网络上的物理延迟,网络的物理延迟指发送单元的输出延迟、总线上信号的传播延迟、接收单元的输入延迟。PTS的时间为以上延迟时间的和的两倍。之后两个PBS1和PBS2意为相位缓冲段,作用就是确定采样点的位置,采样点会在PBS1和PBS2中间。
硬同步也可以叫硬件同步,解决的问题是时接收方第一个采样点与波形的第一位对齐。
这就是位时序周期,可以想象成秒表,总线上每个设备内部都有一个这样的秒表,这个秒表顺时针一直转,每转一圈就是一个数据位的时间,那这个秒表的最佳状态就是所有设备的秒表都时刻处于同一个位置保持同步,比如其中一个设备转到SS段了,那么其他所有设备也都处于SS段。
举个例子假设现在所有秒表同步转动,有一个设备想作为发送方开始一段波形,那么发送方会在自己的秒表转到SS段时开始一个新数据位,即发送方的每次数据跳变都会等自己的秒表转到SS段时产生,这样接收方秒表每次转到SS段接收方就知道一个新的数据位开始了,之后接收方直接在PBS1和PBS2之间进行数据采样,这样正好是想要的采样位置。
如何保证所有设备的秒表都同步转动呢?那就是其他所有接收方收到SOF(就是第一个数据跳变边沿)的下降沿时,这时接收方会把自己的秒表直接拨到SS段与发送方保持同步,因为发送方产生第一个跳变沿肯定也是发送方自己的SS段,这样一个SOF边沿就将所有设备的秒表同步了。
接下来看一下接收方内部的位时序周期:
先看上面那个图,红线画的是总线上的波形,当红线由逻辑高电平跳变到逻辑低电平时,这个下降沿是发送方产生SOF的第一个下降沿,下降沿时刻肯定是发送方的SS段,那接收方一看这个下降沿并不在我的SS段里,所以接收方就直接把自己的SS段与波形下降沿对齐,也就是变成下面这个图,接收方SS段与波形下降沿重合。
再同步也叫重新同步,它的目的就是补偿误差,如果所有设备的时钟都绝对精准那就用不到再同步功能。
SJW自己指定配置为1~4Tq。
先看上面的波形,这个位时序是接收方的,蓝色的线表示总线上发送方发出的波形,比如这个波形之前执行了硬同步,之后传了很多位,到这一位时可以看到当前数据跳变沿出现在了SS段之后,也就是接收方的秒表跑的比发送方快,接收方认为在SS部分就应该出现边沿但实际出现的晚了。所以接收方会执行再同步,在其PBS1段之后额外加上SJW指定的补偿宽度。比如下面那个波形,SJW配置为2(误差也是2Tq),所以PBS1延长2Tq,这样下一次接收方SS段就会往后挪,新的波形跳变沿就会往SS段的方向调整。
这是接收方秒表跑慢了,波形的数据跳变沿就会提前出现,这时接收方就会把它的PBS2段减少SJW指定的宽度。
注意事项:如果误差值小于或者等于SJW指定值,则误差几个Tq就补偿几个Tq。比如误差2Tq,SJW指定3Tq,那实际补偿就是2Tq;如果误差2Tq,SJW指定1Tq,那实际补偿就是指定的1Tq。相当于SJW是再同步补偿宽度的最大限制。
SS = 1Tq,PTS = 3Tq,PBS1 = 3Tq,PBS2 = 3Tq
Tq = 0.5us
波特率 = 1 / (0.5us + 1.5us + 1.5us + 1.5us) = 200kbps
回读机制目的是确认自己发出的电平是否真实地发送出去了。因为根据线与特性,我发送1,如果要别的设备也在发送数据,别的设备发送了0,那么我读回的数据就不再是1了,因为我的数据1被别的设备的数据0损坏了,这个现象对仲裁就很重要,我发出1但是读回的是0,这说明总线上有别的设备,我感知到了别的设备和我的冲突,所以这时候我就退出不再跟别的设备抢总线资源。
规则是:数据位从前到后依次比较,出现差异且数据位为1的设备仲裁失利
单元1第一位SOF是显性0,单元2第一位SOF也是显性0,两个单元同时张开总线,根据线与特性总线呈现显性0,然后单元1回读总线电平是0没问题,单元2回读总线电平是0也没问题,所以单元1和单元2会继续发送,之后依次分析,直到图上红色所示位,单元1的这一位ID号是1,单元1发1,释放总线;单元2的这一位ID号是0,单元2发0,拉开总线。根据线与规则总线呈现显性0状态,之后单元2回读为0和自己发的一样没问题,但是单元1这时候回读也是0,这就有问题了,单元1发的是1读回却是0,这说明有别的设备正在和单元1抢总线,并且在这一位我发1它发0,所以才会呈现出我发1但是读回0的现象,此时刻单元1仲裁失利,之后单元1就转为接收状态。
从仲裁过程可以看出为什么ID号小的优先级高,ID号越小其二进制数据1出现的就越晚,ID号出现差异且发送数据1的仲裁失利。
当有更多设备同时开始,每个设备仍然执行“发一位,回读一位”的流程,一旦回读的和自己发的不一样自己就退出,又因为每个设备发出消息的仲裁段必然不同,所以在仲裁段数据位从前往后的比较中必然会陆续有设备主动退出,并且在仲裁段结束时必然有且只有一个设备操作总线,之后在执行后续数据位的发送就不会再出现多设备冲突的问题了。
位填充会不会影响仲裁呢?首先说明位填充的作用范围是帧起始、仲裁场、控制场、数据场以及CRC序列,所以在仲裁场里会进行为填充。如果填充位会改变A和B的优先级,那填充位前面的位A和B就必须一样,而一旦A和B前面的位一样那么A和B就填充一样的位了。结论就是填充位不会影响仲裁也不会改变原有ID号的优先级。
仲裁段最后一位RTR,遥控帧定义为1,数据帧定义为0,所以有ID号相同时数据帧优先级高于遥控帧。
单元1拓展数据帧ID号的高11位正好和单元2标准数据帧的11位ID号完全一致,下一位单元1发出的是SRR位,SRR位在拓展数据帧中必须始终为1,所以单元1发送数据1;单元2此时要发出RTR位,因为单元2是数据帧,RTR位是0,所以单元2发数据0。单元1仲裁失利转入接收状态。单元2继续发送后续数据。
检测到对应错误时发送单元或者接收单元就会紧跟着主动出击发出错误帧,破坏总线上的数据,发出错误帧的行为就叫错误通知。意思是不管你们其他设备有没有检测到这个错误,反正我现在检测到了错误我要破坏这个数据帧大家都不要收了。
错误通知赋予了每个设备破坏传输的能力,如果有设备无论收到啥都认为是错的,那总线上正常的数据传输都无法完成了,为了防止某一个设备因为自己的问题而干扰正常数据传输,这个限制措施就是错误状态。
TEC是发送错误计数器,设备每发送一个错误这个TEC就会增加一次(注意不是加1),当然每进行一次正常的发送后TEC也会减小一次。REC是接收错误计数器,设备在接收时每发现一个错误这个REC就会增加一次,同样进行正常接收后REC也会减小一次。所以TEC和REC的值反映了当前设备检测错误的相对频率,如果正常传输没几次错误检测到了一堆,那TEC或REC肯定会迅速增加,如果正常传输的次数很多只是偶尔报告了一些错误,那么TEC或REC增加后肯定会迅速减回来。
初始状态是主动错误状态,主动错误状态是比较可靠的状态,如果TEC>127或者REC>127,只要发送或接收有一个不正常就是错误报告相对与正常传输太频繁了,那就把设备转入到被动错误状态,被动错误状态表示设备不太可靠,当然如果在被动错误状态设备又变好了进行了很多正常数据传输,那么TEC或REC就会减小,减小到TEC<=127并且REC<=127后,设备重新回到主动错误状态。但是如果设备在被动错误状态仍然不断报告错误,那么就说明这个设备可能出问题了,所以在TEC>255时,会直接把设备转为总线关闭状态,跟REC没关系。如果设备处于关闭状态,就不能进行通信,但是考虑到这个设备对系统可能有很重要的作用,所以处于总线关闭状态的设备还有一条生路,就是在执行上检测到128次连续11个位的隐形位,总线关闭状态的设备就会直接回到主动错误状态满血复活,TEC和REC都会清零。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。