收需要的报文。
1 几个重要概念
1) 过滤器组
STM32总共提供14个过滤器组来处理CAN接收过滤问题,每个过滤器组包含两个32位寄存器,即CAN_FiR0和CAN_FiR1组成(i=0~13),在设置为屏蔽位模式下,其中一个作为标
识符寄存器,另一个作为屏蔽码寄存器。过滤器组中的每个过滤器,编号(叫做过滤器号)从0开始,到某个最大数值(这时最大值并非13,而是取决于14个过滤器组的模式和位宽的设
置,当全部配置为位宽为16,且为标识符列表模式时,最大编号为14*4-1=55)。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F0R1 |
F0R2 |
F1R1 |
F1R2 |
F2R1 |
F2R2 |
F3R1 |
F3R2 |
F4R1 |
F4R2 |
F5R1 |
F5R2 |
F6R1 |
F6R2 |
F7R1 |
F7R2 |
F8R1 |
F8R2 |
F9R1 |
F9R2 |
F10R1 |
F10R2 |
F11R1 |
F11R2 |
F12R1 |
F12R2 |
F13R1 |
F13R2 |
2 过滤器过滤模式
过滤器过滤模式有屏蔽位模式和过滤器列表模式
1)屏蔽位模式
为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式;
在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。
2)过滤器列表模式
为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式;
在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤
器标识符相同。
3)过滤器的位宽
每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:
? 1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位
? 2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位
4)过滤器组的位宽模式和位宽设置
看手册
5)过滤器匹配序号及优先规则
看手册
2 CAN ID的分析
1) CAN ID分析
标准标识符:ID28~ID18
扩展标识符: ID28~D18 加上 ID17~D0
eg1:有标准标识符为:
0x6D1 (b 110 1101 0001) 占用ID的ID28~ID18,共11位
eg2:有扩展标识符为:
0x1EFEDFEA (b 1 1110 1111 1110 1101 1111 1110 1010) 其中红色部分为基本标识符 粉色部分为扩展标识符
2)位宽为32位的屏蔽模式分析
如上图所示:此种模式下,过滤器包含一个32位的标识符寄存器和一个32位的屏蔽寄存器,灰色部分显示的是与CAN ID各位定位的映射关系。由图可以看出映像关系恰好等于扩展
CAN ID左移3位再加上IDE、RTR及一个显性电平得到。
所以如何将CAN ID所表示的各部分如何针对过滤器寄存器各部分对号入座,其主要是掌握其核心思想即可:1:在各种过滤器模式下,CAN ID与寄存器相应位置一定要匹配;2:在
屏蔽方式下,屏蔽寄存器某位为1表示接收到的CAN ID对应的位必须对验证码寄存器对应的位相同。
eg:下面以代码例子,假设我们要接收多个ID:0x6D1 , 1EFEDFEA, 前面为标准标识符,后面为扩展标识符,要同时能接收这两个标识符的情况来配置过滤器
u16 Std_ID =0x6D1;
u32 Ext_ID =0x1EFEDFEA;
u32 mask =0;
CAN_FilterInitTypeDef CAN_FilterInitStructure; //定义一个结构体变量
CAN_FilterInitStructure.CAN_FilterNumber=0; //设置过滤器组0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //设置过滤器组0为屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //设置过滤器组0位宽为32位
/**************************************************************************************************************************************
标识符寄存器的设置,Ext_ID<<3对齐,再>>16取高16位
***************************************************************************************************************************************/
CAN_FilterInitStructure.CAN_FilterIdHigh=((Ext_ID<<3) >>16) & 0xffff; //设置标识符寄存器高字节。
CAN_FilterInitStructure