STM8/32 CAN过滤器设置详解

CAN总线的标准帧和扩展帧主要决定帧ID的长度,标准帧的帧ID长度是11位,也就是帧ID的范围是000-7FF。扩展帧的帧ID长度是29位,也就是帧ID的范围是0000 0000-1FFF FFFF。CANopen帧ID最多是11位的,因此是标准帧;而SAE 1939协议通常是18XX XXXX的帧ID,是29位的,因此是扩展帧。

在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时-根据标识符的值决定软件是否需要该报文;如果需要,就拷贝到RAM里;如果不需要,报文就被丢弃且无需软件的干预。为满足这一需求,beCAN为应用程序提供了个可配置的、位宽可变的6个(0-5)过滤器组,用于只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件进行过滤,从而占用一定的CPU资源。每个过滤器组x包含8个8位寄存器 CAN_FxR[8:1].

STM8S208的beCAN有6个过滤器,它们之间是并联的,也就是说只要通过任意一个过滤器,报文就会被拷贝到RAM。

beCAN位宽可变性:
    每个过滤器组的位宽都可以独立配置,以满足应用程序的不同需求。根据位宽的不同,每个过可以配置成以下位宽:
─ 1 个32 位过滤器,包括: STDID[10:0]/EXTID[28:18]、IDE、 EXID[17:0] RTR
─ 2个 16 位过滤器,包括: STDID[10:0]/EXTID[28:18]、IDE、 RTR

─ 4个8 位过滤器,包括:STDID[10:3]/EXTID[28:21],其他位可以不用关心;
─ 1个16位过滤器和 2个 8位过滤器,具体的过滤器描述如上16位和 8位过滤器描述。

STDID:标准ID,有11位。

EXTID: 扩展ID,有29位。

IDE :当等于0时表示标准ID, 当等于1时表示扩展ID

RTR:当等于0时表示数据帧, 当等于1时表示远程帧(remote frame)

beCAN的工作模式:

beCAN提供了两种工作模式:屏蔽位模式和标识符列表模式。如下例所示:

typedef enum
{
  CAN_FilterMode_IdMask                  =  ((uint8_t)0x00),    /*!< id/mask mode */
  CAN_FilterMode_IdMask_IdList           =  ((uint8_t)0x10),    /*!< Id/Mask mode First and IdList mode second */
  CAN_FilterMode_IdList_IdMask           =  ((uint8_t)0x11),    /*!< IdList mode First and IdMask mode second */
  CAN_FilterMode_IdList                  =  ((uint8_t)0x01)     /*!< identifier list mode */
}CAN_FilterMode_TypeDef;

在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。

在标识符列表模式下,屏蔽寄存器当作标识符寄存器用。因此,使用2个标识符来代替上面的标识符加屏蔽位的方式。接收报文标识的每一位都必须跟过滤器标识符相同。

32位过滤器寄存器定义如下:


举个例子:设置过滤器0只接收ID为0x1828A0EF的数据帧。(工作在屏蔽位模式)

该帧ID超过11位,为扩展帧ID。二进制表示为

1 1000 0010 1000 1010 0000 1110 1111

前11位ID(EXID[28:18],对应寄存器位置[31:21])为1100 0001 010,EXID[17:15](寄存器位置[20:18])为001,EXID[14:7](寄存器位置[15:8])为0100 0001,EXID[6:0](寄存器位置[7:1])为1101 111。

寄存器的第17位IDE,设置为1时表示扩展帧ID,设置为0表示标准帧ID。寄存器的第16位RTR,设置为1时表示远程帧,设置为0时表示数据帧。寄存器第一位([0])为保留位,设为0。

本例中RTR应设为0,IDE应设为1。

所以32位寄存器的设置为1100 0001 0100 1001 0100 0001 1101 1110

其中绿色位置为RTR,黄色位为IDE,红色为为保留位0。16进制表示为0xC1 49 41 DE。

工作在屏蔽位模式时,我们可以指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。如果Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR7

都为0xFF时报文ID必须匹配所有的位才能通过过滤器。当Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR7都为0x00时,所有的报文都可以通过过滤器。CAN_FilterIDMask1~4对应Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR7。本例中应该都设置为0xFF。

设置代码如下所示:

CAN_FilterNumber =CAN_FilterNumber_0;

CAN_FilterMode =CAN_FilterMode_IdMask;

CAN_FilterScale =CAN_FilterScale_32Bit;

CAN_FilterID1=0xc1; 

CAN_FilterID2=0x49;

CAN_FilterID3=0x41;

CAN_FilterID4=0xde;

CAN_FilterIDMask1=0xFF;//CAN_FilterIDMask1~4是一个32位的寄存器,用来设置Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR8。

CAN_FilterIDMask2=0xFF;

CAN_FilterIDMask3=0xFF;

CAN_FilterIDMask4=0xFF;

CAN_FilterIDMask1~4也是一个32位的寄存器,用来设置Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR8,与CAN_FilterID1~4的32位一一对应。IDMask寄存器里的某一位设为1代表传进来的报文必须和过滤器Identifier寄存器对应的该位匹配,设为0代表Identifier寄存器中的该位不需要关心是否匹配。

再看一个例子:设置ID过滤器0只接收ID为0x20XXXX的数据帧。

首先这个ID大于0x7FF,是扩展帧。因为还是数据帧,所以IDE设为1,RTR设为0。拓展ID第29位到17位([28:16])为0 0000 0010 0000。

过滤器ID寄存器设置为0000 0001 0000 1000 0000 0000 0000 0000.

其中绿色位置为RTR,黄色位为IDE,棕色位及以后的都不影响最后的ID。红色为为保留位0。16进制表示为0x01 08 00 00。

IDMask寄存器应在棕色位以前为1,棕色位起以后为0。即1111 1111 1111 1110 0000 0000 0000 0000,16进制为0xFF FE 00 00。设置代码如下所示:

CAN_FilterNumber =CAN_FilterNumber_0;

CAN_FilterMode =CAN_FilterMode_IdMask;

CAN_FilterScale =CAN_FilterScale_32Bit;

CAN_FilterID1=0x01; 

CAN_FilterID2=0x08;

CAN_FilterID3=0x00;

CAN_FilterID4=0x00;

CAN_FilterIDMask1=0xFF;//CAN_FilterIDMask1~4是一个32位的寄存器,用来设置Can_FxR5、Can_FxR6、Can_FxR7、Can_FxR8。

CAN_FilterIDMask2=0xFE;

CAN_FilterIDMask3=0x00;

CAN_FilterIDMask4=0x00;

如果IDMask寄存器没有正确配置好的话,会使得ID寄存器的某些位不起作用(比如对应的IDMask被设置成了0)。比如下面的例子:

CAN_Filter_Structure.FilterNumber = CAN_FilterNumber_0;//ID过滤
CAN_Filter_Structure.FilterActivation = ENABLE;
CAN_Filter_Structure.FilterMode = CAN_FilterMode_IdMask;
CAN_Filter_Structure.FilterScale = CAN_FilterScale_32Bit;
CAN_Filter_Structure.FilterID1=0x01;
CAN_Filter_Structure.FilterID2=0x00;
CAN_Filter_Structure.FilterID3=0;
CAN_Filter_Structure.FilterID4=0;
CAN_Filter_Structure.FilterIDMask1=0xff;
CAN_Filter_Structure.FilterIDMask2=0xe6;
CAN_Filter_Structure.FilterIDMask3=0;
CAN_Filter_Structure.FilterIDMask4=0;

IDMask寄存器被设置成了1111 1111 1110 0110 0000 0000。RTR和IDE对应的位被设置成了0,也就是说RTR和IDE的设置被忽略。因此,只要满足ID为扩展帧ID0x20XXXX和标准帧ID0x008,帧格式无论是数据帧还是远程帧的报文都可以通过。





猜你喜欢

转载自blog.csdn.net/jirryzhang/article/details/79728967