STM8 CAN总线的IdMask模式的讲解
在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时根据标识符的值决定软件是否需要该报文;如果需要,就拷贝到RAM里;如果不需要,报文就被丢弃且无需软件的干预。为满足这一需求,BeCAN为应用程序提供了个可配置的、位宽可变的6个(0-5)过滤器组,用于只接收那些软件需要的报文。硬件过滤的做法节省了CPU开销,否则就必须由软件进行过滤,从而占用一定的CPU资源。
一、IdMask模式
首先,需要明白IdMask的作用:
举个例子吧,过滤器长度为32位,模式为屏蔽模式,假如我要发送的标示符为0x1314;那过滤器设置如下
1、过滤器完全无效 接收到的标示符全部通过
0x1314 二进制码: 00000000 0000 0000 0001 0011 0001 0100
CAN_Filter xxxx xxxx xxxx xxxx xxxx xxxxxxxx xxxx
CAN_FilterMask 0000 0000 0000 0000 00000000 0000 0000
因为 CAN_FilterMask屏蔽寄存器所有位都是0 ,对应标识符全为“不关心”,也就是接收到数据的ID(标识符)不用与 CAN_Filter寄存器的任何一位进行匹配。
2、过滤器完全有效 接收到的标识符要跟据CAN_FilterMask寄存器指定需要匹配的位进行与CAN_Filter比较。
部分匹配 :
0x1314 二进制码: 00000000 0000 0000 0001 0011 0001 0100
CAN_Filter xxxx xxxx xxxx xxxx xxxx xxx1 xxxx xxxx
CAN_FilterMask 0000 0000 0000 0000 0000 0001 0000 0000
CAN_FilterMask 寄存器指定接收到的标示符要与第8位进行匹配,其他位不管。也就是说接收到的标示符第8位必须为1,否则报文就会被丢弃。
全部匹配:
0x1314 二进制码: 00000000 0000 0000 0001 0011 0001 0100
CAN_Filter 0000 0000 0000 0000 0000 0011 0001 0100
CAN_FilterMask 1111 1111 1111 1111 1111 1111 1111 1111
这种情况最为严格,接收到的标示符必须每一位都得与过滤器中的标示符的每一位进行匹配,有一位不对报文就会被丢弃。(这个标示符匹配的工作是CAN 模块内部硬件自动完成的)
二、IdMask库代码
本程序中,使用的软件代码是:
软件:
\STM8S_StdPeriph_Lib\Project\STM8S_StdPeriph_Examples\CAN\CAN_Networking路径下面的代码。
硬件:
STM8/128 EVAL板子,上面的MCU为STM8S208MBT6B ;
程序里面打开了接收的中断:
为了能够更有效的操作实践这一功能,我使用了如上图的CAN总线的分析仪器USB-CAN200 以及它的上位机.
在这里需要说明一点,将R0+与R0-相短接,则内部的120欧姆的电阻会被接入总线,不需要画蛇添足,在R0+与R0-之间自己再找一个120欧姆的电阻外部接上!!
在接收中断里面已经有现成的标准桢结构,所以设置好Idfliter或者Idmask就可以。
也就是上面的 这一段函数;
按照刚才的理解,
如果我的扩展id是0x12345678 ;想只接收0x12xxxxxx的标识符号,那么是否填入
CAN_FilterID1 = 0x12 ;
CAN_FilterIDMask = 0xFF
就可以了呢? 本以为是这样,结果通过上位机发出去之后,led板上的符号并没有变化;说明并没有接收到。这是为什么呢?
所以对于扩展的ID号码它有29位,但是程序中设计的过滤器位32位,所以:
如果假设扩展id为0x12345678(0001,0010,0011,0100,0101,0110,0111,1000)
所以扩展id的顺序填入如上图所示意,这儿假设:
RTR位我们设置为0表示数据帧,IDE位设置为1表示扩展ID,因为我们的ID是29位的,所以RTR = 0; IDE = 1;
再来看我们参考手册中,定义的 :
将上面数据中的标示符号位再填入到过滤器中:
所以可以看到颜色的顺序已经被打乱了,
如果要关心到具体的某一个比特位置;如果要过滤器让它只接收0x12xxxxxx的标识符号;
这时候要根据它实际在identifier中的位置去修改idmask ; 前八个比特,对应的就是黄色和绿色的部分,
所以其他的颜色,可以都填0表示不需要关心,则这里填入:1 1 1 1 ,1 xx x,我们这里填入0xF8 ;
即:
CAN_FilterID1=0x91;
CAN_FilterID2=0x00;
CAN_FilterID3=0x00;
CAN_FilterID4=0x00;
CAN_FilterIDMask1=0xF8; //0
CAN_FilterIDMask2=0x00; //0
CAN_FilterIDMask3=0x00; //0x0
CAN_FilterIDMask4=0x00; //
同理,对于下面的配置是只接收标准id=0x321(0011,0010,0001)的ID(也是32位过滤器),
因为也是数据帧,所以RTR = 0,标准的id,所以IDE= 0 ;所以填入到:
CAN_FilterID1=0x64;
CAN_FilterID2=0x20;
CAN_FilterID3=0x00;
CAN_FilterID4=0x00;
CAN_FilterIDMask1=0xFF; //0
CAN_FilterIDMask2=0xE0; //0
CAN_FilterIDMask3=0x0; //0x0
CAN_FilterIDMask4=0x0; //
如下图,测试通过
STM8CAN总线IdMask模 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)