STM32自带了基本扩展CAN外设,又称bxCAN,bxCAN的特点如下:
支持CAN协议2.0A和2.0B主动模式
波特率最高达1Mbps
支持时间触发通信
具有3个发送邮箱
具有3级深度的2个接收FIFO
可变的筛选器组(也称过滤器组,最多28个)
模式
工作模式:
通过CAN_MCR寄存器控制INRQ和SLEEP
①初始化模式(INRQ=1,SLEEP=0)
②正常模式(INRQ=0,SLEEP=0)
③睡眠模式(SLEEP=1)
测试模式:
通过CAN_BTR寄存器控制LBKM和SILM
①静默模式( LBKM=0,SILM=1 )
②环回模式( LBKM=1,SILM=0 )
③环回静默模式(LBKM=1,SILM=1)
调试模式
CAN控制器框图如下:
两个 CAN 都分别拥有自己的发送邮箱和接收 FIFO,但是他们共用 28 个 滤波器。通过 CAN_FMR 寄存器的设置,可以设置滤波器的分配方式。
标识符筛选器
CAN的标识符不表示目的地址而是表示发送优先级。接收节点根据标识符的值,来决定是否接收对应消息。
STM32 CAN控制器,提供了28个可配置的筛选器组(F1仅互联型才有28个,其他的只有14个),可降低CPU处理CAN通信的开销。
STM32 CAN控制器每个筛选器组由2个32位寄存器组成(CAN_FxR1和CAN_FxR2,x=0~27)。根据位宽不同,每个筛选器组可提供:
● 1个32位筛选器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位
● 2个16位筛选器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位
筛选器可配置为:屏蔽位模式和标识符列表模式。在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。而在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟筛选器标识符相同。
通过CAN_FM1R和CAN_FS1R可配置筛选器的位宽和模式:
为了过滤出一组标识符,应该设置筛选器组工作在屏蔽位模式。
为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。
应用程序不用的筛选器组,应该保持在禁用状态(通过CAN_FA1R设置)。
筛选器组中的每个筛选器,都被编号为(即:筛选器编号)从0开始,到某个最大数值-取决于筛选器组的模式和位宽的设置。
通过CAN_FFA1R的设置,可以将筛选器组关联到FIFO0/FIFO1
例:设置筛选器组0工作在:1个32位筛选器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而0XFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0XFFxx00xx,才算是正确的(x表示不关心)。
CAN发送流程
CAN发送流程为: 程序选择1个空置的邮箱(TME=1)->设置标识符(ID),数据长度和发送数据->设置CAN_TIxR的TXRQ位为1,请求发送->邮箱挂号(等待成为最高优先级)->预定发送(等待总线空闲)->发送->邮箱空置。
CAN接收流程
报文FIFO具有锁定功能(由CAN_MCR,RFLM位控制),锁定后,新数据将丢弃,不锁定则新数据将替代老数据
CAN接收流程为: FIFO空收到有效报文->挂号_1(存入FIFO的一个邮箱,这个由硬件控制,我们不需要理会)->收到有效报文->挂号_2->收到有效报文->挂号_3->收到有效报文->溢出。
CAN收到的有效报文,存储在3级邮箱深度的FIFO中。FIFO接收到的报文数,我们可以通过查询CAN_RFxR的FMP寄存器来得到,只要FMP不为0,我们就可以从FIFO读出收到的报文。
位时序
STM32的CAN将传播时间段和相位缓冲时间段1合并成时间段1
设TS1=6、TS2=5、BRP=5,波特率=42000/[(7+6+1)*6]=500Kbps。
寄存器简介
CAN主控制寄存器(CAN_MCR)
该寄存器的我们仅介绍下INRQ位,该位用来控制初始化请求。 设置INRQ=0,可使CAN从初始化模式进入正常工作模式。 设置INRQ=1,可使CAN从正常工作模式进入初始化模式 。
CAN初始化时,先设置INRQ=1 ,进入初始化模式,进行初始化(尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置INRQ=0,进入正常工作模式。
CAN位时序寄存器(CAN_BTR)
CAN接收FIFO寄存器(CAN_RF0R/CAN_RF1R)
CAN_RF0R用于FIFO0控制
CAN_RF1R用于FIFO1控制
CAN发送邮箱标识符寄存器(CAN_TIxR)(x=0~2)
CAN发送邮箱数据长度和时间戳寄存器 (CAN_TDTxR) (x=0~2)
TIME[15:0]和TGT位,用于时间戳相关设置
CAN发送邮箱数据寄存器(CAN_TDLxR/CAN_TDHxR) (x=0~2)
图为CAN_TDLxR寄存器的描述,用于存储低4个字节的数据。CAN_TDHxR寄存器与之类似,用于存储高4个字节的数据。要发送的数据就是存储在这两个寄存器。
CAN接收FIFO邮箱标识符寄存器(CAN_RIxR)(x=0/1)
CAN接收FIFO邮箱数据长度和时间戳寄存器(CAN_RDTxR) (x=0/1)
TIME[15:0],用于时间戳相关设置,FMI用于存储筛选器匹配索引
CAN接收FIFO邮箱邮箱数据寄存器(CAN_RDLxR/CAN_RDHxR) (x=0/1)
图为CAN_RDLxR寄存器的描述,用于存储低4个字节的数据。CAN_RDHxR寄存器与之类似,用于存储高4个字节的数据。接收到的数据就存储在这两个寄存器。
CAN筛选器模式寄存器(CAN_FM1R)
该寄存器设置筛选器的工作模式,必须在CAN_FMR寄存器FINIT=1时配置,对于STM32F103ZET6,只有[13:0]位有效,对于互联性STM32F1或者STM32F407,则全部有效。
CAN筛选器尺度寄存器(CAN_FS1R)
该寄存器用于设置筛选器的位宽,必须在CAN_FMR寄存器FINIT=1时配置,对于STM32F103ZET6,只有[13:0]位有效,对于互联性STM32F1或者STM32F407,则全部有效。
CAN筛选器FIFO关联寄存器(CAN_FFA1R)
该寄存器设置报文通过筛选器组之后,被存入的FIFO,如果对应位为0,则存放到FIFO0;如果为1,则存放到FIFO1。该寄存器也只能在过滤器处于初始化模式( CAN_FMR 寄存器的FINIT=1 )下配置。
CAN筛选器激活寄存器(CAN_FA1R)
该寄存器用于设置筛选器组的开启和关闭。对对应位置1,即开启对应的筛选器组;置0则关闭该筛选器组。
CAN筛选器组i寄存器x(CAN_FiRx)(i=0~27,x=1/2)
每个筛选器组的CAN_FiRx都由2个32位寄存器构成,即:CAN_FiR1和CAN_FiR2。根据过滤器位宽和模式的不同设置,这两个寄存器的功能也不尽相同。关于过筛选器的映射,功能描述和屏蔽寄存器的关联,在前面已经介绍过了。
初始化流程
①配置相关引脚的复用功能,使能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的FINIT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。