作者:嵌软小白呗
在上一章的《AUTOAR CP入门》中,我们大概了解一下Autosar和入门Autosar的方法。另外,上一章也说到,学习Autosar CAN通讯开发应该先学习跟逻辑相关的东西,这样更容易入门,等到入门之后,再往下学习CAN驱动相关的东西。
但是,总不能都搞CAN开发了,但是连CAN是什么东西,CAN通讯要怎么接线都不知道吧?
所以,接下来,我会先把CAN物理层的东西,并且是经常要实际用到的CAN物理层的知识讲一下。
另外,由于此时是CAN入门,关于CAN物理层的很多的深入的细节都会略过,比如错误帧、CAN报文的各个段、ACK等等,这些内容大部分都是要解决一些CAN问题时才用得到。而且,另外还有很多是CAN开发中基本用不上的概念,这篇文章就不那么深入讲解了。
如果一开始学习就全部概念都去看,大多是看的一知半解,而且学了这些概念对软件开发没有特别大的帮助,反而打击了学习信心和欲望。
实际上,等到后面接触多了CAN的东西,碰到相关问题时,自然就会有一种渴望去学习这些最底层的CAN相关知识。
CAN开发,CAN开发,所以肯定要先知道CAN是个什么东西。
首先,大家第一次真正接触CAN,是不是通过电脑CAN上位机软件看到很多的CAN数据在不断刷屏?
每个人用的设备可能不一样,但是都是一个CAN盒、两根CAN线(CANH/CANL)、一个终端电阻(或CAN盒自带终端电阻、或板子自带终端电阻)、一个板子、一台电脑。
没关系,下面我们从物理层面入手,把上面这张图拆解开。
实际上,我们的电脑和CAN盒就是一个模拟的CAN节点。
刚接触可能看不太懂上面的图,没关系,我们从这张图截取一个CAN节点来看,梳理一下CAN通信需要的硬件东西都有些什么,并且有什么用,然后就明白了:
注意它是一条双绞线,就是像麻花一样卷一起的两条线,数据是通过这两条线传输的。绞在一起目的是抗干扰的,为什么能抗干扰,我们下面马上讲到。
就是因为在这根双绞线的两头最远处才需要接的电阻,只需要两个就行了,每个120Ω。原因就难解释了,涉及到各种物理知识,我也不看的一知半解,我们目前只需要知道,CAN要正常通讯,一定要有这玩意就行。
这时,你想起来一开始那张图,好像只有一个终端电阻啊!
但是,你认真想了想,发现大家平时确实都这样接:单板接CAN盒然后再接一个120Ω的终端电阻,最后再把CAN盒接到电脑上。
那么,为什么明明CAN标准里的要求其实是CAN总线的两端各需要接一个终端电阻,即两个120Ω的终端电阻并联,总阻值为60Ω,但我们平时调试的时候只接了一个就能正常通讯了呢?
据我所知,CAN总线要正常通讯,并联1~4个终端电阻(总电阻120Ω~30Ω)都是能正常通讯的。终端电阻的使用与CAN总线的长度和CAN节点的放置有关系,在整车CAN总线规划的时候,终端电阻会根据CAN总线长度和节点的放置决定阻值。
而我们平时调试,只要能正常通讯就行了,要求不需要那么严格。
首先要知道:CAN数据是通过CANH和CANL的差分信号进行传输的。
看下面这张图,图中的是CANH和CANL进行数据传输时的电压情况:
隐性电平:CANH和CANL差值为0V时称为隐性电平(实际上,隐性电平的正常电压范围是:-0.5V~0.05V),代表逻辑1。
显性电平:CANH和CANL差值为2V称为显性电平(实际上,显性电平的正常电压范围是:1.5V~3V),代表逻辑0(一般我都这么记:显灵显灵,逻辑0)。
另外,CAN通讯的目的就是传输数据嘛,而数据在芯片的世界里只能用逻辑0和逻辑1表示,但是CAN总线需要用两根线的差分信号表示逻辑0和逻辑1,怎么办呢?
接收数据时:把(CANH/CANL)的差分电平转换成逻辑电平,并通过RX引脚传给MCU的CANRX。这样MCU就收到CAN总线的数据了,像下面这样:
发送数据时:把CANTX发过来的逻辑电平,转换成(CANH/CANL)的差分电平发送出去。这样MCU就把数据发到CAN总线了,像下面这样:
好了,到现在为止,你应该明白了CAN总线的物理层是怎么一回事。
另外,我们上面还遗留一个双绞线为什么抗干扰的问题。
既然我们知道了CAN总线传输数据的方式是差分信号,那么你想想,由于我们的CANH和CANL是双绞线,出现干扰时就会同时干扰两条线,如下面这张图:
假设由于干扰导致CANH和CANL的电压都上升了1V。
CANH变成了4.5V,CANL变成了2.5V。但是:4.5V-2.5V还是等于2V。所以,这并不影响正常通讯。因此,双绞线是能抗干扰的。
好了,关于CAN总线要工作起来,物理层面所有需要的东西,我们总结一下:
①双绞线、②终端电阻、③收发器、④带有CAN控制器的MCU(这个入门先不管它,知道要有就行了)。
有这几样东西之后,只要我们MCU的CAN驱动代码是正常的,那么就能正常通讯了。
好了,了解了CAN物理层面都要些什么具体的东西之后,我们接下来看看什么是CAN报文。
02.什么是CAN报文(以标准CAN格式报文为例)
想起当时还没接触CAN的时候,听到别人提到CAN报文、CAN帧这些东西,总是在想,报文?帧?这什么东西。
大哥啊,我只是想知道什么是报文,感觉应该不难吧???为什么要讲得这么专业,生怕我入行抢饭碗是吧,还是,我太菜了,根本看不懂。。。
现在,按照我的理解,所谓的一帧CAN报文,通俗来讲就是:CAN节点发送到CAN总线的一个数据包。
如下图所示,图中有四帧CAN报文。(用示波器探头测量CANL或CANH):
把这3张图一结合,是不是马上对CAN报文有了一个更深刻的认识?
可见,一帧CAN报文的组成还是挺多东西的,但是,对我们平时使用来说,我们只看到两个段:
2、数据段,也就是这一帧CAN报文具体传输的数据内容。
其它部分:帧起始、控制段、CRC段、ACK段、帧结束,这些是一帧报文固定有的东西,CAN盒在发送或接收报文时会按照CAN标准协议解析这些地方,对我们现在只是简单认识CAN报文和使用CAN报文,暂时不需要去深究它们。
实际上,我们经常接触的除了上面的标准CAN格式报文,还有另外3种常接触的CAN报文,如下图所示:
表中列出来的是平时应用过程中,对不同CAN格式报文我们需要知道的关键差异,对入门来说,只要知道这些就够了。
知道了什么是CAN报文,接下来,就要去看看CAN报文具体是怎么发到CAN总线了。
我们要知道,CAN数据传输方式是广播式的。也就是一对多,一个CAN节点发的CAN报文,其它CAN节点都能够接收到。
就像很多人在同一个房间一样,每个人什么时候都能说话,而且房间是正常大小,只要一个人正常说话,其他人都能听到。
因此,这里马上就能想到一个问题:如果两个节点同时往外发报文怎么办?
所以,CAN总线如果出现多个CAN节点同时发送报文时,会有仲裁机制。
仲裁发生的位置就在CAN报文的仲裁段(报文ID)上。
关于仲裁,我们这里有个结论:报文ID越小,优先级越高。
我们先认识一下“线与”的概念:显性覆盖隐性,当电路通路时,有一个端点接地(GND),那么整个电路电压就为零了。
因此:(逻辑电平0) & (逻辑电平1) = (逻辑电平0)
所以,我们举个例子就能理解为什么仲裁机制中,CANID越小,优先级越高了,如下图所示:两个CAN控制器同时发送CAN报文,当CANID发到第8位时,由于0x123的第8位是0,0x128的第8位是1,因此,CAN总线表现为逻辑0,0x123报文仲裁胜利。
那么,CAN控制器怎么就知道自己仲裁成功还是仲裁失败了?
所以,CAN控制器还有一个机制:发出数据时,会进行回读。
简单理解,就是CAN控制器通过TX脚发出一帧CAN报文的时候,会通过CAN控制器的RX脚进行回读,如果读到自己发出去的逻辑电平跟自己会读到的逻辑电平不一致,在仲裁段时就会停止发报文,在其它段则产生错误帧。
当发出0x128报文的节点发到CANID的第8位时,它发现,明明自己发出去的是逻辑电平1,但读回来就变成了逻辑电平0,因为总线电平被0x123的第8位拉成0。
仲裁失败的一方,则退出CAN报文的发送,等待仲裁胜利的报文发送完成后再次发送,若继续出现与其它节点同时发送报文的情况,则继续仲裁。
所以,依靠着仲裁机制,CAN总线上即便很多CAN节点接上去,然后任意发CAN报文都不会有啥问题了。
当知道了CAN的物理链路,了解了什么是CAN报文。
于是,你兴致勃勃的按照上面的接线方法,接好板子、接上CAN线,接好CAN线、还有终端电阻,再CAN盒接上电脑。
没办法,我们不知道是多少,只能问别人,于是,人家告诉你这这个板子的波特率是这么选。然后点击确认,报文就开始出来。
反正报文出来了就行,这个板子的波特率就这么选,记住就好了嘛。
但是,我们可是CAN开发工程师啊,可不能说连个波特率为啥要这么选都不知道啊。
首先,我们要知道仲裁域波特率是指哪个位置的波特率,数据域波特率又是指哪个位置的波特率。
仲裁域波特率(注意,仲裁域波特率并不是单指仲裁域,而是除去数据域的其它地方的波特率):
另外,CAN格式的报文,数据域和仲裁域都是一样的波特率。所以,只要选一个仲裁域的就好了。
对于CANFD格式的报文,数据域和仲裁域是不同的波特率。所以,数据域和仲裁域的波特率都要选。
这就要根据代码里配置的波特率是多少了,而代码配置为多少,又是根据需求来的了。
实际上,波特率我是这样理解的:如波特率500k,即1秒/500k=2微秒,也就是说,最小2微秒可以进行一次电平变化,1秒最多可以电平变化500k次。(这个最小2us的一次变化的电平,这个叫做位时间)
可见,标准CAN格式报文的长度(物理层次)为:1+11+1+1+1+4+0(64)+15+1+1+1+7=44~108位。
我们上面还说了,500K波特率的话,位时间是2us。
所以,对于500K波特率的标准CAN格式报文,数据域长度为64bit时,我们在示波器可以看到是这样的:
即,一帧报文的时间长度是:108bit * 2us = 116us。
好了,关于仲裁域波特率和数据域波特率的认识就到这里了。
到这里为止,我们从CAN总线物理层需要的东西,到CAN报文是什么,再到CAN报文在CAN总线上的传输、到CAN波特率都大致了解了一遍。
这回是不是就明白了,我们从CAN上位机看到的CAN报文,究竟是怎么来的。 这篇文章的目的是为了能迅速认识什么是CAN总线和CAN报文,很多关于CAN通讯平时用不上的深入细节都省略了,等到最后这个CAN通讯开发系列快结束的时候,在写CAN驱动时再深入讲解,这样就更容易理解了。
实际上,对CAN入门来说,只要知道CAN的物理链路要怎么去接线,CAN报文是什么东西,这样就能进行CAN通讯开发了,比如CAN应用报文开发、网管报文开发、报文超时故障开发、CAN诊断开发等等。
好了,接下来就可以步入CAN开发了。但是,要开发总得有需求吧?总不能一上来啥需求也不知道,咔咔咔一顿开发,都不知道开发了啥。
下一篇文章,我们会看看CAN通讯开发的需求都是些什么。
原文始发于微信公众号(谦益行):《小白的AUTOSAR BSW软件开发历程》02-从实际应用层面认识CAN报文