前语
在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; //
如下图,测试经过
四、附录
在CAN规范中并未界说代表逻辑电平的物理状况(例如电压),iCAN网络运用契合ISO11898-2规范的电平信号,一般来讲,CAN总线为“隐性”(逻辑1)时,CAN_H和CAN_L的电平为2.5V(电位差为0V);CAN总线为“显性”(逻辑0)时,CAN_H和CAN_L的电平分别是3.5V和1.5V(电位差为2.5V)。
辨认符
辨认符—规范格局 辨认符的长度为11 位,相当于扩展格局的根本ID(Base ID)。这些位按ID-28 到ID-18 的次序发送。最低位是ID-18。7 个最高位(ID-28- ID-22)有必要不能满是“隐性”。
辨认符—扩展格局 和规范格局构成比照,扩展格局由29 位组成。其格局包含两个部分:11 位根本ID、18 位扩展ID。
根本ID:根本ID 包含11 位。它按ID-28 到ID-18 的次序发送。它相当于规范辨认符的格局。根本ID界说扩展帧的根本优先权。
扩展ID:扩展ID 18 位。它按ID-17 到ID-0 次序发送。 规范帧里,辨认符这以后是RTR 位。 RTR 位(规范格局以及扩展格局) RTR 的全称为“长途发送恳求位(RemoteTransmission Request BIT)”。 RTR 位在数据帧里有必要为“显性”,而在长途帧里有必要为“隐性” 。
扩展格局里,根本ID 首要发送,其次是IDE 位和SRR 位。扩展ID 的发送位与SRR 位之后。
SRR 位(扩展格局)
SRR 的全称是“替代长途恳求位(SubstituteRemote Request BIT)”。
SRR 是一隐性位。它在扩展格局的规范帧RTR 位方位,因而替代规范帧的RTR 位。
规范帧与扩展帧的抵触是经过规范帧优先于扩展帧这一途径得以处理,扩展帧的根本ID(拜见以下的“扩展辨认符”)好像规范帧的辨认符。
IDE 位(扩展格局) IDE 的全称是“辨认符扩展位(IdentifierExtension Bit)”
IDE 位归于:
– 扩展格局的裁定场
– 规范格局的操控场
规范格局里的IDE位为“显性(逻辑0)”,而扩展格局里的IDE位为“隐性”。
在标识符列表形式下,屏蔽存放器当作标识符存放器用。因而,运用2个标识符来替代上面的标识符加屏蔽位的方法。接纳报文标识的每一位都有必要跟过滤器标识符相同。
设置过滤器0只接纳ID为0x1828A0EF和0x1828A0EE的数据帧。(作业在标识符列表形式)
首要咱们把这两个ID写成二进制:
0x1828A0EF: 00011000001010001010000011101111
0x1828A0EE: 00011000001010001010000011101110
然后咱们将0x1828A0EF二进制的格数据组成如上图mapping所示的格局
Cna_fxr1:1100 0001 0xc1
Cna_fxr2:01001001 0x49 //这儿有个RTR位咱们设置为0表明数据帧,IDE位设置为1表明扩展ID,
Cna_fxr3:0100 0001 0x41
Cna_fxr4:1101 1110 0xDE
这时咱们作业在标识符列表形式,identifier/Mask的存放器相当于identifier运用。
再将0x1828A0EE二进制的格数据组成如上图mapping所示的格局
Cna_fxr5:1100 0001 0xc1
Cna_fxr6:01001001 0x49 //这儿有个RTR位咱们设置为0表明数据帧,IDE设置为1表明扩展ID
Cna_fxr7:0100 0001 0x41
Cna_fxr8:1101 1100 0xDC
以下是用库函数装备的程序小片段:
CAN_FilterNumber =CAN_FilterNumber_0;
//留意这是的形式是跟IdMask例不相同的
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;
信任看到这儿你对这两种作业形式都会有了必定的了解。好了,到此比如就介绍完了,算是抛砖引玉。8位、16位的位宽是类似的,跟上面的剖析相同。