一、CAN控制器简介
STM32自带了基本扩展CAN外设,又称bxCAN,bxCAN的特点如下:
1、支持CAN协议2.0A和2.0B主动模式
2、波特率最高达1Mbps
3、支持时间触发通信
4、具有3个发送邮箱
5、具有3级深度的2个接收FIFO
6、可变的筛选器组(也称过滤器组,最多28个)
CAN控制器简介-模式
工作模式
1)初始化模式(INRQ=1,SLEEP=0)
2)正常模式(INRQ=0,SLEEP=0)
3)睡眠模式(SLEEP=1)
通过CAN_MCR寄存器控制INRQ和SLEEP
测试模式
1)静默模式(LBKM=0,SILM=1)
(静默模式下bxCAN可以接收CANRX但是不会发送任何CANTX,可以监控总线上的数据)
2)环回模式(LBKM=1,SILM=0)
(环回模式下bxCAN可以发送CANTX但是不会接收任何CANRX。它发送的数据,发送与接收会形成一个环路,从而达到自发自收的作用,可以自己检测发送的数据是否发送出去)
3)环回静默模式(LBKM=1,SILM=1)
(不管总线上如何都不影响,自发自收,“闭关锁国”)
通过CAN_BTR寄存器控制LBKM和SILM
https://blog.csdn.net/weixin_62584795/article/details/126686162
————————————————
STM32的CAN控制器可以对接收到的数据报文进行过滤。
只接收指定CAN ID的数据。
对于其他CAN ID发送过来的数据,则不再触发CAN中断。
根据芯片的不同,可以有不同数量的CAN控制器:
如果STM32只有一个CAN控制器,则可以配置14个过滤器组,对应的编号为0 ~ 13。
如果STM32拥有两个CAN控制器,则可以配置28个过滤器组:
对于CAN 1,对应的过滤器组编号为0 ~ 13。
对于CAN 2,对应的过滤器组编号为14 ~ 27。
CAN过滤有如下模式:
屏蔽位模式
标识符列表模式
相关寄存器
和CAN过滤相关的寄存器为CAN_FxR1和CAN_FxR2:
如果只想接收CAN ID为0x317的标准帧,则设置方法如下:
0110 0010 111:0x317对应的二进制位。
1111 1111 111:收到的数据帧中相应的ID位必须和设置的ID位一样。
00和11:只接收标准帧,不接收扩展帧。
如果想接收CAN ID为0x310至0x317的标准帧,则设置方法如下:
代码实例
只过滤一个CAN ID
如果需要让CAN 2只接收CAN ID为0x713的报文,则代码如下:
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 14;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; // 屏蔽位模式?
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = ( uint16_t ) ( ( 0x713 << 5 ) & 0xFFFF );
CAN_FilterInitStructure.CAN_FilterIdLow = ( uint16_t ) ( 0x0000 | CAN_ID_STD );
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFF0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0006;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit ( &CAN_FilterInitStructure );
过滤多个CAN ID
如果需要让CAN 2只接收CAN ID为0x713、0x714的报文,则代码如下:
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber = 14;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = ( uint16_t ) ( ( 0x713 << 5 ) & 0xFFFF );
CAN_FilterInitStructure.CAN_FilterIdLow = ( uint16_t ) ( 0x0000 | CAN_ID_STD );
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFF0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0006;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit ( &CAN_FilterInitStructure );
/*-----------------------------------------------------------------------------------*/
CAN_FilterInitStructure.CAN_FilterNumber = 15;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = ( uint16_t ) ( ( 0x714 << 5 ) & 0xFFFF );
CAN_FilterInitStructure.CAN_FilterIdLow = ( uint16_t ) ( 0x0000 | CAN_ID_STD );
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFF0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0006;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit ( &CAN_FilterInitStructure );
————————————————
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)