CAN
文章目录
- CAN
- 一、配置
- 1、对扩展数据帧进行过滤:(只接收扩展数据帧)
- CAN_FilterIdHigh:
- CAN_FilterIdLow:
- 2、对扩展远程帧过滤:(只接收扩展远程帧)
- 3、对标准远程帧过滤:(只接收标准远程帧)
- 4、对标准数据帧过滤:(只接收标准数据帧)
- 5、对扩展帧进行过滤:(只接收扩展帧)
- 6、对标准帧进行过滤:(只接收标准帧)
- 二、CAN过滤器详解
- 2.1 过滤器
- 2.2 过滤器的过滤模式
- 2.2.1 屏蔽位模式
- 2.2.2 标识符列表模式
- 2.3 过滤器的位宽
- 2.3 过滤器组的过滤模式和位宽设置
一、配置
(slave_id=0x18010001为只接收的id号):
1、对扩展数据帧进行过滤:(只接收扩展数据帧)
CAN_FilterInitStructure.CAN_FilterIdHigh=(((u32)slave_id<<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow=(((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
CAN_FilterIdHigh:
这一步是为了从32位的slave_id中提取出高16位作为CAN过滤器的ID高位部分。
(u32)slave_id << 3:首先将slave_id强制转换为32位的无符号整数(u32),然后将其左移3位。这是为了将slave_id向左移动3位,为后续的位运算做准备。
& 0xFFFF0000:然后将结果与0xFFFF0000进行按位与操作。0xFFFF0000是一个32位的十六进制数,它的二进制表示是11111111111111110000000000000000。这个操作会将结果的低16位全部变为0,只保留高16位的内容。>> 16:最后将上一步的结果右移16位。这个操作是为了将之前保留的高16位部分移到最低的16位中,这样就得到了最终的ID高位部分。
因此,整个操作的目的是从32位的slave_id中提取出高16位,并放置到CAN_FilterInitStructure.CAN_FilterIdHigh中,以用作CAN过滤器的ID高位部分。
CAN_FilterIdLow:
这一步是为了从32位的slave_id中提取出低16位,并添加扩展帧和数据帧标志位,最后将结果进行掩码操作。
(u32)slave_id << 3:首先将slave_id强制转换为32位的无符号整数(u32),然后将其左移3位。这是为了将slave_id向左移动3位,为后续的位运算做准备。
| CAN_ID_EXT | CAN_RTR_DATA:然后将上一步的结果与CAN_ID_EXT和CAN_RTR_DATA进行按位或操作。CAN_ID_EXT代表扩展帧标志位,CAN_RTR_DATA代表数据帧标志位。通过按位或操作,可以将这两个标志位添加到ID的低16位部分。
& 0xFFFF:最后将上一步的结果与0xFFFF进行按位与操作。0xFFFF是一个16位的十六进制数,它的二进制表示是1111111111111111。这个操作会将结果的高16位全部变为0,只保留低16位的内容。
因此,整个操作的目的是从32位的slave_id中提取出低16位,并将扩展帧和数据帧标志位添加到其中,最后进行掩码操作,得到最终的ID低位部分,并放置到CAN_FilterInitStructure.CAN_FilterIdLo中,以用作CAN过滤器的ID低位部分。
2、对扩展远程帧过滤:(只接收扩展远程帧)
CAN_FilterInitStructure.CAN_FilterIdHigh = (((u32)slave_id<<3)&0xFFFF0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
3、对标准远程帧过滤:(只接收标准远程帧)
CAN_FilterInitStructure.CAN_FilterIdHigh =(((u32)slave_id<<21)&0xffff0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
4、对标准数据帧过滤:(只接收标准数据帧)
CAN_FilterInitStructure.CAN_FilterIdHigh =(((u32)slave_id<<21)&0xffff0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
5、对扩展帧进行过滤:(只接收扩展帧)
CAN_FilterInitStructure.CAN_FilterIdHigh =(((u32)slave_id<<3)&0xFFFF0000)>>16;CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<3)|CAN_ID_EXT)&0xFFFCAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
6、对标准帧进行过滤:(只接收标准帧)
CAN_FilterInitStructure.CAN_FilterIdHigh =(((u32)slave_id<<21)&0xffff0000)>>16;
CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)slave_id<<21)|CAN_ID_STD)&0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFC;
二、CAN过滤器详解
2.1 过滤器
STM32总共提供14个过滤器组来处理CAN接收过滤问题,每个过滤器组包含两个32位寄存器CAN_FxR0和CAN_FxR1组成,在设置为屏蔽位模式下,其中一个作为标识符寄存器,另一个作为屏蔽码寄存器。过滤器组中的每个过滤器,编号(叫做过滤器号)从0开始,到某个最大数值(这时最大值并非13,而是取决于14个过滤器组的模式和位宽的设置,当全部配置为位宽为16,且为标识符列表模式时,最大编号为14*4-1=55)。
2.2 过滤器的过滤模式
STM32提供两种过滤模式供用户设置:屏蔽位模式和标识符列表模式。
2.2.1 屏蔽位模式
为了过滤出一组标识符,应该设置过滤器组工作在屏蔽位模式。
在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。
2.2.2 标识符列表模式
为了过滤出一个标识符,应该设置过滤器组工作在标识符列表模式。
在标识符列表模式下,屏蔽寄存器也被当作标识符寄存器用。因此,不是采用一个标识符加一个屏蔽位的方式,而是使用2个标识符寄存器。接收报文标识符的每一位都必须跟过滤器标识符相同。
2.3 过滤器的位宽
每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过滤器组可提供:●1个32位过滤器,包括:STDID[10:0]、EXTID[17:0]、IDE和RTR位●2个16位过滤器,包括:STDID[10:0]、IDE、RTR和EXTID[17:15]位
2.3 过滤器组的过滤模式和位宽设置
过滤器组可以通过相应的CAN_FMR寄存器(CAN过滤器主控寄存器)配置。但是不是什么时候都可以直接配置,在配置一个过滤器组前,必须通过清除CAN_FAR寄存器(CAN过滤器激活寄存器)的FACT位,把它设置为禁用状态。然后才能设置或设置过滤器组的配置。
通过设置CAN_FS1R(CAN过滤器位宽寄存器)的相应FSCx位,可以配置一个过滤器组的位宽。
通过CAN_FM1R(CAN过滤器模式寄存器)的FBMx位,可以配置对应的屏蔽/标识符寄存器的标识符列表模式或屏蔽位模式。
这些大家可以看一下。
2.4 过滤器匹配序号
一旦收到的报文被存入FIFO,就可被应用程序访问。通常情况下,报文中的数据被拷贝到SRAM中;为了把数据拷贝到合适的位置,应用程序需要根据报文的标识符来辨别不同的数据。bxCAN提供了过滤器匹配序号,以简化这一辨别过程。
根据过滤器优先级规则,过滤器匹配序号和报文一起,被存入邮箱中。因此每个收到的报文,都有与它相关联的过滤器匹配序号。过滤器匹配序号可以通过下面两种方式来使用:● 把过滤器匹配序号跟一系列所期望的值进行比较● 把过滤器匹配序号当作一个索引来访问目标地址对于标识符列表模式下的过滤器(非屏蔽方式的过滤器),软件不需要直接跟标识符进行比较。对于屏蔽位模式下的过滤器,软件只须对需要的那些屏蔽位(必须匹配的位)进行比较即可。
在给过滤器编号时,并不考虑过滤器组是否为激活状态。另外,每个FIFO各自对其关联的过滤器进行编号。
后面在做补充(今晚10点之前)