/*****我所理解的stm8_CANbus过滤器—Sandy*********Start offile*************/
文件名:我所理解的stm8_CANbus过滤器—Sandy
作者:手术刀
QQ:872180981
Time :2015-7-18
/***************************瘟 鸡工 作 室********************************/
stm8CANbus过滤器详细描述
在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
EXTID: 扩展ID
IDE :当等于0时表示标准ID, 当等于1时表示 扩展ID
RTR:当等于0时表示 数据帧, 当等于1时表示遥控帧。
beCAN的工作模式:
beCAN提供了两种工作模式:屏蔽位模式和标识符列表模式
在屏蔽位模式下,标识符寄存器和屏蔽寄存器一起,指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。
在标识符列表模式下,屏蔽寄存器当作标识符寄存器用。因此,使用2个标识符来代替上面的标识符加屏蔽位的方式。接收报文标识的每一位都必须跟过滤器标识符相同。
以上参考stm8数据手册!!
相关例子看下页
配置实例:
前面讲了那么多,下面我们来看看几个例子吧。
1.设置过滤器0只接收ID为0x1828A0EF的数据帧。(工作在屏蔽位模式)
首先我们把这个ID写成二进制:0001 1000 0010 1000 1010 0000 1110 1111
然后我们将二进制的格数据组成如上图mapping所示的格式
Cna_fxr1:1100 0001 0xc1
Cna_fxr2:0100 1001 0x49 //这里有个RTR位我们设置为零表示数据帧,IDE 位设置为1表示扩展ID,因为我们的ID是29位的
Cna_fxr3:0100 0001 0x41
Cna_fxr4:1101 1110 0xDE
这样我们的四个identifier数据这根据mapping的格式做好了。
那么identifier/Mask是干什么的呢?工作在屏蔽位模式时,我们可以指定报文标识符的任何一位,应该按照“必须匹配”或“不用关心”处理。如果Cna_fxr5、Cna_fxr6、Cna_fxr7、Cna_fxr8都为0xFF时报文ID必须匹配所有的位才能通过过滤器。当Cna_fxr5、Cna_fxr6、Cna_fxr7、Cna_fxr8都为0x00时,所有的报文都可以通过过滤器。因此在本例中应该全为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_FilterIDMask2=0xFF;
CAN_FilterIDMask3=0xFF;
CAN_FilterIDMask4=0xFF;
2.设置过滤器0只接收ID为0x1828A0EF和0x1828A0EE的数据帧。(工作在标识符列表模式)
首先我们把这两个ID写成二进制:
0x1828A0EF: 0001 1000 0010 1000 1010 0000 1110 1111
0x1828A0EE: 0001 1000 0010 1000 1010 0000 1110 1110
然后我们将0x1828A0EF二进制的格数据组成如上图mapping所示的格式
Cna_fxr1:1100 0001 0xc1
Cna_fxr2:0100 1001 0x49 //这里有个RTR位我们设置为零表示数据帧,IDE位 设置为1表示扩展ID,因为我们的ID是29位的
Cna_fxr3:0100 0001 0x41
Cna_fxr4:1101 1110 0xDE
这时我们工作在标识符列表模式,identifier/Mask的寄存器相当于identifier使用。
再将0x1828A0EE二进制的格数据组成如上图mapping所示的格式
Cna_fxr5:1100 0001 0xc1
Cna_fxr6:0100 1001 0x49 //这里有个RTR位我们设置为零表示数据帧,IDE位 设置为1表示扩展ID,因为我们的ID是29位的
Cna_fxr7:0100 0001 0x41
Cna_fxr8:1101 1100 0xDC
以下是用库函数配置的程序小片段:
CAN_FilterNumber =CAN_FilterNumber_0;
//注意这是的模式是跟第一个例不一样的
CAN_FilterMode =CAN_FilterMode_IdList;
CAN_FilterScale =CAN_FilterScale_32Bit;
CAN_FilterID1=0xc1;
CAN_FilterID2=0x49;
CAN_FilterID3=0x41;
CAN_FilterID4=0xde;
CAN_FilterIDMask1=0xc1;
CAN_FilterIDMask2=0x49;
CAN_FilterIDMask3=0x41;
CAN_FilterIDMask4=0xdc;
相信看到这是你对这两种工作模式有一定的了解了吧!下面我们再来个关于接收某个范围ID的例子吧。
3.设置只接收0x1828A080到0x1828A0FF的数据帧(工作在屏蔽位模式)
首先我们把这两个ID写成二进制:
0x1828A080 : 0001 1000 0010 1000 1010 0000 1000 0000
0x1828A0FF : 0001 1000 0010 1000 1010 0000 1111 1111
然后我们将0x1828A0--二进制的格数据组成如上图mapping所示的格式
Cna_fxr1:1100 0001 0xc1
Cna_fxr2:0100 1001 0x49 //这里有个RTR位我们设置为零表示数据帧,IDE位 设置为1表示扩展ID,因为我们的ID是29位的
Cna_fxr3:0100 0001 0x41
Cna_fxr4:---- ---0 0x??
这里问题来了Cna_fxr4我们要填什么值呢?先看看Cna_fxr5、Cna_fxr6、Cna_fxr7、Cna_fxr8的设置吧。
Cna_fxr5:1111 1111 0xFF
Cna_fxr6:1111 1111 0xFF
Cna_fxr7:1111 1111 0xFF
Cna_fxr8:0000 0000 0x00
在Cna_fxr8中我们设置为不关心[6:0]位 所以Cna_fxr4的高[1:7]位我们可以填任何值[0]位要为0就可以了。这里我们就随便填个0xfe吧!
以下是用库函数配置的程序小片段:
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=0xFE;
CAN_FilterIDMask1=0xFF;
CAN_FilterIDMask2=0xFF;
CAN_FilterIDMask3=0xFF;
CAN_FilterIDMask4=0x00;
这样我们就配置好了只接收0x1828A080到0x1828A0FF的数据帧了。
好了,例子就说完了,8位16位的位宽是相似的,请自己研究吧。
/***************我所理解的XXX—Sandy**************End offile*************/