CAN是Controller Area Network的缩写,是ISO的国际标准化的串行通信协议。在当前的汽车产业中,有各种各样的电子控制系统,这些系统之间所用的数据类型及对可靠性的要求不尽相同。1986年电气商博世公司开发出面向汽车的CAN通信协议。现在,CAN的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面。
CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐形电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。
CAN的特点:
多主控制。总线空闲时,所有单元都可以发送消息;最先访问总线的单元优先;同时发送看ID优先级。
消息的发送。所有消息以固定的格式发送;ID不是地址,是访问总线的优先级;2个以上单元同时发送消息,会对ID进行逐位仲裁。
系统的柔软性。没有“地址”信息;总线增加单元时,软硬件不需要改变。
通信速度。根据整个网络的规模,设定合适的速度;同一网络,必须统一通信速度。
远程数据请求。可通过发“遥控帧”,请求其他单元发送数据。
错误检测功能、错误通知功能、错误恢复功能。所有单元都可以检测错误;检测出错误的单元会通知其他单元;正在发送消息的单元一旦检测出错误会强制结束当前的发送;强制结束的单元会不断重新发送直到成功为止。
故障封闭。CAN可以判断出错误类型是暂时的数据错误(如外部噪声等);或是持续的数据错误(如单元内部故障,驱动器故障,断线等);当为持续故障时,可将引起故障的单元隔离。
连接。CAN总线可同时连接多个单元的总线;可连接的单元总数理论上没有限制;实际上,降低通信速度,可连接单元数增加,提高通信速度,可连接的单元数减少。
CAN协议经过ISO标准化后有两个标准,ISO11898标准和ISO11519-2标准,该标准的物理层特性如下图所示;
ISO11898物理层特性
从该特性可以看出,显性电平对应逻辑“0”;CAN_H和CAN_L之差为2.5V左右;而隐形电平对应逻辑“1”;CAN_H和CAN_L之差为0V。在总线上显性电平具有优先权,只要一个单元输出显性电平,总线上即为显性电平。而隐形电平则具有包容的意味,只有所有的单元都输出隐形电平,总线上才为隐形电平;另外,在CAN总线的起始端都有一个120欧的终端电阻,来做阻抗匹配,以减少回波反射。
CAN协议分为以下5种类型的帧;
各种帧及其用途
由于篇幅所限,接下来着对数据帧进行介绍;数据帧分为7个部分,若下图所示;
结合下面的标识符寄存器来分析有哪些比较重要的信息,
寄存器的[31:3]位用来存储数据帧的ID,标准格式只用到[31:21]位。
寄存器的位2是IDE,该位是用来判断标准格式还是扩展格式,当为1时,为扩展格式,当为0时,为标准格式。
寄存器的位1是RTR,该位是用来判断是数据帧还是遥控帧,当为1时,为遥控帧,当为0时,为数据帧。
接下来看数据长度寄存器,位[3:0]为DLC,指定数据长度,最多8个字节。
接下来为两个高低字节数据寄存器,用来存放数据;
上面的寄存器是发送邮箱的寄存器,接收邮箱的寄存器几乎一样,可参考STM32中文手册,对比一下。
接下来介绍位时序,每秒钟发送的位数叫做位速率,一个位可以分为4段:同步段(ss)、传播时间段(PTS)、相位缓冲段1(PBS1)、相位缓冲段2(PBS2);每个段又由若干个Tq构成,Tq为最小的时间单位。
所以只要更改TS1[3:0],TS2[2:0],BRP[9:0]这几个位,就能设置相应的波特率。对于STM32F103这块芯片,它的CAN时钟是由APB1时钟提供的,最大为36MHZ,设TS1=8,TS2=7,BRP=3,就可以得到500Kbps的波特率。
在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者,节点在接收报文时,根据标识符的值,决定软件是否需要该报文,如果需要,叫拷贝到SRAM里,如果不需要,报文就丢弃且无需软件的干预。
为满足这一需求,bxCAN控制器就为应用程序提供了若干个位宽可变、可配置的过滤器组(互联型28个,其他产品14个)。以便只接收那些软件需要的报文,硬件过滤的做法节省了CPU开销,否则就必须由软件过滤从而占用一定的CPU开销。每个过滤器组x由2个32位寄存器,CAN_FiR0和CANFiR1组成(互联产品中i=0~27,其他产品i=0~13)。
在设置过滤器模式、位宽、FIFO关联寄存器之前,要将CAN_FMR的位0 FINIT设置为初始化模式。
过滤器分为屏蔽位模式和标识符列表两种模式;
屏蔽位模式是指屏通过蔽寄存器CAN_FiR2与标识符寄存器CAN_FiR1搭配,当屏蔽寄存器为1时,接收到的标识符必须与标识符寄存器对应的位一致,才能被接收;当屏蔽寄存器为0时,接收到的标识符与标识符寄存器对应的位可以不同,举例:
标识符寄存器CAN_FiR1 0xFFFF 0000;
蔽寄存器CAN_FiR2 0xFF00 FF00;
只有当接收到的报文为 0xFFxx 00xx格式的才能被接收(x表示0或1),
每组过滤器组的位宽都可以独立配置,以满足应用程序的不同需求,根据位宽的不同,每个过滤器组可提供:
1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位;
或者 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位。
上述的不同
配置可以产生下面的情况;
共有两个接收邮箱FIFO0和FIFO1,通过下面的寄存器决定数据存储在哪个接收FIFO。
过滤器规则:在接收一个报文时,其标识符首先与配置在标识符列表模式下的过滤器相比较,如果匹配上,报文就被存放到相关联的FIFO中,并且所匹配的过滤器的序号被存放到FMI,如果没有匹配,报文标识符就接着与配置在屏蔽模式下的过滤器进行比较。如果报文标识符没有跟过滤器中的任何标识符相匹配,那么硬件就丢弃该报文,且不会对软件有任何打扰。
配置相关引脚的复用功能,使能CAN时钟;要用CAN,要先使能CAN的时钟,CAN的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用,这里我们需要设置PA11为上拉输入(CAN_RX引脚),PA12为复用输出(CAN_TX引脚),并使能PA口的时钟。
设置CAN工作模式及波特率;通过先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位,再通过CAN_BTR设置波特率和工作模式(正常模式、环回模式)等信息。最后设置INRQ为0,退出初始化模式。
设置滤波器;本例程,我们将使用筛选器组0,并工作在32位标识符屏蔽位模式下。要先设置CAN_FMR的FINT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。
1、从官方封装的CAN初始化程序分析寄存器如何被操作
检验参数是否合理
退出睡眠模式,进入初始化模式,并开始等待初始化确认并计时,如果当时间等于INAK_TIMEOUT且还未初始化成功时,退出while返回错误状态;如果当初始化成功,退出while循环。并对使能的位进行设置。
对BTR寄存器的位31、30进行模式设置,并设置波特率,接着退出初始化模式。等待退出初始化确认,如果在INAK_TIMEOUT这个时间内成功退出,返回成功状态,否则返回失败状态。
2、从官方封装的CAN过滤器初始化程序分析寄存器如何被操作
首先将CAN过滤器进入初始化模式,然后对选择的过滤器禁用。
如果选择的位宽是16位,则CAN_FS1R对应的位清零。
如果选择的位宽是32位,则CAN_FS1R对应的位置1。
如果选择屏蔽位模式,CAN_FM1R对应位清零;如果选择标识符模式,CAN_FM1R对应位置1。
如果选择关联到FIFO0,则CAN_FFA1R对应位清零;如果选择关联到FIFO1,则CAN_FFA1R对应位置1。
如果使能过滤器激活,则对CAN_FA1R置1,最后退出初始化模式。
3、从官方封装的发送函数看寄存器如何被操作
首先依次查询0~2哪个邮箱为空,如果都不为空,返回状态没有空闲邮箱。
根据IDE判断是标准标识符还是扩展标识符,并将标识符数据存入发送邮箱。
并把发送数据长度DLC以及数据存入发送邮箱。最后对TXRQ位置1,来请求发送邮箱的数据。当数据发送完成,邮箱为空时,硬件对该位清零。
4、从官方封装的发送函数看寄存器如何被操作
与发送函数相反,接收函数从邮箱把数据存到结构体变量RxMessage中,然后对RFOM0或RFOM1置1,释放邮箱。
1、CAN子函数
2、主函数
通过按键KEY0可以切换正常模式和环回模式,正常模式需要两块开发板才能做实验,所以选择环回模式,按下KEY_UP能发送数据,而且只能接收自己发送的数据。