STM32
直播中

wufan931111

10年用户 1164经验值
擅长:370217
私信 关注
[问答]

CAN发送接收流程是怎样的?

CAN协议具有哪些特点?

STM32F4的bxCAN的主要特点是什么?
CAN发送接收流程是怎样的?

回帖(1)

崔家骁

2021-10-22 16:12:58
                     一.CAN简介

  CAN是ControllerArea Network的缩写(以下称为CAN),是ISO国际标准化的串行通信协议。在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个LAN,进行大量数据的高速通信”的需要,1986年德国电气商博世公司开发出面向汽车的CAN通信协议。此后,CAN通过ISO11898及ISO11519进行了标准化,现在在欧洲已是汽车网络的标准协议。 现在,CAN的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。现场总线是当今自动化领域技术发展的热点之一,被誉为自动化领域的计算机局域网。它的出现为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。
  CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。
  CAN协议具有一下特点:

  1)多主控制。在总线空闲时,所有单元都可以发送消息(多主控制),而两个以上的单元同时开始发送消息时,根据标识符(Identifier以下称为 ID)决定优先级。ID并不是表示发送的目的地址,而是表示访问总线的消息的优先级。两个以上的单元同时开始
  发送消息时,对各消息ID的每个位进行逐个仲裁比较。仲裁获胜(被判定为优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。
  2)系统的柔软性。与总线相连的单元没有类似于“地址”的信息。因此在总线上增加单元时,连接在总线上的其它单元的软硬件及应用层都不需要改变。
  3)通信速度较快,通信距离远。最高1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps)。
  4)具有错误检测、错误通知和错误恢复功能。所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。
  5)故障封闭功能。CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
  6)连接节点多。CAN总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。正是因为CAN协议的这些特点,使得CAN特别适合工业过程监控设备的互连,因此,越来越受到工业界的重视,并已公认为最有前途的现场总线之一。CAN协议经过ISO标准化后有两个标准:ISO11898标准和ISO11519-2标准。其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准,而ISO11519-2是针对通信速率为125Kbps以下的低速通信标准。
  我们使用的是500Kbps的通信速率,使用的是ISO11898标准,该标准的物理层特征如图所示:
   
  

  

  从该特性可以看出,显性电平对应逻辑0,CAN_H和CAN_L之差为2.5V左右。而隐性
  电平对应逻辑1,CAN_H和CAN_L之差为0V。在总线上显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平。而隐形电平则具有包容的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平(显性电平比隐性电平更强)。另外,在CAN总线的起止端都有一个120Ω的终端电阻,来做阻抗匹配,以减少回波反射。
  CAN协议是通过以下5种类型的帧进行的:

  数据帧
  遥控帧
  错误帧
  过载帧
  间隔帧
  另外,数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有11个位的标识符(ID),扩展格式有29个位的ID。各种帧的用途如表所示
  
  

  

  由于篇幅所限,我们这里仅对数据帧进行详细介绍,数据帧一般由7个段构成,即:
  (1)帧起始。表示数据帧开始的段。
  (2)仲裁段。表示该帧优先级的段。
  (3)控制段。表示数据的字节数及保留位的段。
  (4)数据段。数据的内容,一帧可发送0~8个字节的数据。
  (5) CRC段。检查帧的传输错误的段。
  (6) ACK段。表示确认正常接收的段。
  (7)帧结束。表示数据帧结束的段。
  数据帧的构成如图所示:
  
  

  

  图中D表示显性电平,R表示隐形电平(下同)。
  帧起始,这个比较简单,标准帧和扩展帧都是由1个位的显性电平表示帧起始。
  仲裁段,表示数据优先级的段,标准帧和扩展帧格式在本段有所区别,如图所示
  
  

  

  标准格式的ID有11个位。从ID28到ID18被依次发送。禁止高7位都为隐性(禁止设定:ID=1111111XXXX)。扩展格式的 ID 有29个位。基本ID从ID28到ID18,扩展ID由ID17到ID0表示。基本ID和标准格式的ID相同。禁止高7位都为隐性(禁止设定:基本ID=1111111XXXX)。其中RTR位用于标识是否是远程帧(0,数据帧;1,远程帧),IDE位为标识符选择位(0,使用标准标识符;1,使用扩展标识符),SRR位为代替远程请求位,为隐性位,它代替了标准帧中的RTR位。
  控制段,由6个位构成,表示数据段的字节数。标准帧和扩展帧的控制段稍有不同,如图所示:
  
  

  

  上图中,r0和r1为保留位,必须全部以显性电平发送,但是接收端可以接收显性、隐性及任意组合的电平。DLC段为数据长度表示段,高位在前,DLC段有效值为0~8,但是接收方接收到9~15的时候并不认为是错误。数据段,该段可包含0~8个字节的数据。从最高位(MSB)开始输出,标准帧和扩展帧在这个段的定义都是一样的。如图所示:
  
  

  

  此段CRC的值计算范围包括:帧起始、仲裁段、控制段、数据段。接收方以同样的算法计算 CRC 值并进行比较,不一致时会通报错误。
  ACK段,此段用来确认是否正常接收。由ACK槽(ACK Slot)和ACK界定符2个位组成。
  标准帧和扩展帧在这个段的格式也是相同的。如图所示:
  
  

  

  发送单元的ACK,发送2个位的隐性位,而接收到正确消息的单元在ACK槽(ACK Slot)
  发送显性位,通知发送单元正常接收结束,这个过程叫发送ACK/返回ACK。发送 ACK 的是在既不处于总线关闭态也不处于休眠态的所有接收单元中,接收到正常消息的单元(发送单元不发送ACK)。所谓正常消息是指不含填充错误、格式错误、CRC错误的消息。帧结束,这个段也比较简单,标准帧和扩展帧在这个段格式一样,由7个位的隐性位组成。
  接下来,我们再来看看CAN的位时序。
  由发送单元在非同步的情况下发送的每秒钟的位数称为位速率。一个位可分为 4段。
  同步段(SS)
  传播时间段(PTS)
  相位缓冲段1(PBS1)
  相位缓冲段2(PBS2)
  这些段又由可称为 Time Quantum(以下称为Tq)的最小时间单位构成。
  1位分为4个段,每个段又由若干个Tq构成,这称为位时序。
  1位由多少个Tq构成、每个段又由多少个Tq构成等,可以任意设定位时序。通过设定位时序,多个单元可同时采样,也可任意设定采样点。各段的作用和 Tq数如表所示:
  
  

  

  1个位的构成如图所示:
  
  

  

  上图的采样点,是指读取总线电平,并将读到的电平作为位值的点。位置在 PBS1 结束处。根据这个位时序,我们就可以计算CAN通信的波特率了。具体计算方法,我们等下再介绍,前面提到的CAN协议具有仲裁功能,下面我们来看看是如何实现的。
  在总线空闲态,最先开始发送消息的单元获得发送权。
  当多个单元同时开始发送时,各发送单元从仲裁段的第一位开始进行仲裁。连续输出显性电平最多的单元可继续发送。实现过程,如图所示:
  
  

  

  上图中,单元1和单元2同时开始向总线发送数据,开始部分他们的数据格式是一样的,
  故无法区分优先级,直到T时刻,单元1输出隐性电平,而单元2输出显性电平,此时单元1仲裁失利,立刻转入接收状态工作,不再与单元2竞争,而单元2则顺利获得总线使用权,继续发送自己的数据。这就实现了仲裁,让连续发送显性电平多的单元获得总线使用权。
  二.STM32 CAN介绍

  STM32F4自带的是bxCAN,即基本扩展CAN。它支持CAN协议2.0A和2.0B。它的设计目标是,以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。对于安全紧要的应用,bxCAN提供所有支持时间触发通信模式所需的硬件功能。
  STM32F4的bxCAN的主要特点有:
  支持CAN协议2.0A和2.0B主动模式
  波特率最高达1Mbps
  支持时间触发通信
  具有3个发送邮箱
  具有3级深度的2个接收FIFO
  可变的过滤器组(28个,CAN1和CAN2共享)
  在STM32F407ZGT6中,带有2个CAN控制器,而我们本章只用了1个CAN,即CAN1。
  双CAN的框图如图所示
  
  

  

  从图中可以看出两个CAN都分别拥有自己的发送邮箱和接收FIFO,但是他们共用28个
  滤波器。通过CAN_FMR寄存器的设置,可以设置滤波器的分配方式。
  STM32F4的标识符过滤是一个比较复杂的东东,它的存在减少了CPU处理CAN通信的开销。STM32F4的过滤器(也称筛选器)组最多有28个,每个滤波器组x由2个32为寄存器,CAN_FxR1和CAN_FxR2组成。
  STM32F4每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:
  ● 1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位
  ● 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位
  此外过滤器可配置为,屏蔽位模式和标识符列表模式。
  在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。
  通过CAN_FMR寄存器,可以配置过滤器组的位宽和工作模式,如图所示
  
  

  

  为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。
  为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。
  应用程序不用的过滤器组,应该保持在禁用状态。
  过滤器组中的每个过滤器,都被编号为(叫做过滤器号,图32.1.11中的n)从0开始,到某个最大数值-取决于过滤器组的模式和位宽的设置。
  举个简单的例子,我们设置过滤器组0工作在:1个32位过滤器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即我们希望收到的ID(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而0XFF00FF00就是设置我们需要必须关心的ID,表示收到的ID,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的ID必须是0XFFxx00xx,才算是正确的(x表示不关心)。
   
  接下来,我们看看STM32F4的CAN发送和接收的流程。
  CAN发送流程

  CAN发送流程为:程序选择1个空置的邮箱(TME=1)设置标识符(ID),数据长度和发送数据设置CAN_TIxR的TXRQ位为1,请求发送邮箱挂号(等待成为最高优先级)预定发送(等待总线空闲)发送邮箱空置。整个流程如图所示:
  
  

  

  上图中,还包含了很多其他处理,终止发送(ABRQ=1)和发送失败处理等。通过这个流程图,我们大致了解了CAN的发送流程,后面的数据发送,我们基本就是按照此流程来走。
   
  接下来再看看CAN的接收流程。
  CAN接收流程

  CAN接收到的有效报文,被存储在3级邮箱深度的FIFO中。FIFO完全由硬件来管理,从而节省了CPU的处理负荷,简化了软件并保证了数据的一致性。应用程序只能通过读取FIFO输出邮箱,来读取FIFO中最先收到的报文。这里的有效报文是指那些正确被接收的(直到EOF都没有错误)且通过了标识符过滤的报文。前面我们知道CAN的接收有2个FIFO,我们每个滤波器组都可以设置其关联的FIFO,通过CAN_FFA1R的设置,可以将滤波器组关联到FIFO0/FIFO1。
  CAN接收流程为:FIFO空收到有效报文挂号_1(存入FIFO的一个邮箱,这个由硬件控制,我们不需要理会)收到有效报文挂号_2收到有效报文挂号_3收到有效报文溢出。
  这个流程里面,我们没有考虑从FIFO读出报文的情况,实际情况是:我们必须在FIFO溢出之前,读出至少1个报文,否则下个报文到来,将导致FIFO溢出,从而出现报文丢失。每读出1个报文,相应的挂号就减1,直到FIFO空。CAN接收流程如图所示:
  
  

  

  FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP
  不为0,我们就可以从FIFO读出收到的报文。
  接下来,我们简单看看STM32F4的CAN位时间特性,STM32F4的CAN位时间特性和之前我们介绍的,稍有点区别。STM32F4把传播时间段和相位缓冲段1(STM32F4称之为时间段1)合并了,所以STM32F4的CAN一个位只有3段:同步段(SYNC_SEG)、时间段1(BS1)和时间段2(BS2)。STM32F4的BS1段可以设置为1~16个时间单元,刚好等于我们上面介绍的传播时间段和相位缓冲段1之和。STM32F4的CAN位时序如图所示:
  
  

  

  图STM32F4 CAN位时序
  图中还给出了CAN波特率的计算公式,我们只需要知道BS1和BS2的设置,以及APB1
  的时钟频率(一般为42Mhz),就可以方便的计算出波特率。比如设置TS1=6、TS2=5和BRP=5,在APB1频率为42Mhz的条件下,即可得到CAN通信的波特率=42000/[(7+6+1)*6]=500Kbps。接下来,我们介绍一下本章需要用到的一些比较重要的寄存器。首先,来看CAN的主控制寄存器(CAN_MCR),该寄存器各位描述如图
  
  

  

  仅介绍下INRQ位,该位用来控制初始化请求。
  软件对该位清0,可使CAN从初始化模式进入正常工作模式:当CAN在接收引脚检测到连续的11个隐性位后,CAN就达到同步,并为接收和发送数据作好准备了。为此,硬件相应地对CAN_MSR寄存器的INAK位清’0’。
  软件对该位置1可使CAN从正常工作模式进入初始化模式:一旦当前的CAN活动(发送
  或接收)结束,CAN就进入初始化模式。相应地,硬件对CAN_MSR寄存器的INAK位置’1’。所以我们在CAN初始化的时候,先要设置该位为1,然后进行初始化(尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置该位为0,让CAN进入正常工作模式。
  第二个,我们介绍CAN位时序寄存器(CAN_BTR),该寄存器用于设置分频、Tbs1、Tbs2以及Tsjw等非常重要的参数,直接决定了CAN的波特率。另外该寄存器还可以设置CAN的工作模式。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分