单片机/MCU论坛
直播中

Jessie唐

8年用户 703经验值
擅长:嵌入式技术 制造/封装 接口/总线/驱动
私信 关注
[资料]

STM8 CAN 总线的 IdMask 模式的讲解

前言
学习了 STM8 的 CAN 总线的 IdMask 模式。在 CAN 协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的。 因此,发送者以广播的形式把报文发送给所有的接收者。节点在接收报文时-根据标识符的值决定软件是否需要该报文;如 果需要,就拷贝到 RAM 里;如果不需要,报文就被丢弃且无需软件的干预。为满足这一需求,beCAN 为应用程序提供了个 可配置的、位宽可变的 6 个(0-5)过滤器组,用于只接收那些软件需要的报文。硬件过滤的做法节省了 CPU 开销,否则就 必须由软件进行过滤,从而占用一定的 CPU 资源。
一、IdMask 模式
首先,需要明白 IdMask 的作用:
举个例子吧,过滤器长度为 32 位,模式为屏蔽模式,假如我要发送的标示符为 0x1314;那过滤器设置如下 1、过滤器完全无效 接收到的标示符全部通过
0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100
    CAN_Filterxxxx  xxxx  xxxx xxxx xxxx  xxxx  xxxx xxxx CAN_FilterMask0000 0000  0000 0000 0000 0000 0000 0000

因为 CAN_FilterMask 屏蔽寄存器所有位都是 0 ,对应标识符全为“不关心”,也就是接收到数据的 ID(标识符)不用与

CAN_Filter 寄存器的任何一位进行匹配。
2、过滤器完全有效 接收到的标识符要跟据 CAN_FilterMask 寄存器指定需要匹配的位进行与 CAN_Filter 比较
部分匹配
0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100
CAN_Filterxxxx  xxxx xxxx  xxxx xxxx xxx1  xxxx  xxxx CAN_FilterMask0000 0000 0000 0000 0000 0001 0000 0000

CAN_FilterMask 寄存器指定接收到的标示符要与第 8 位进行匹配,其他位不管。也就是说接收到的标示符第 8 位必须为 1,

否则报文就会被丢弃。
全部匹配
0x1314 二进制码: 0000 0000 0000 0000 0001 0011 0001 0100
CAN_Filter0000 0000 0000 0000 0000 0011 0001 0100
CAN_FilterMask1111 1111 1111 1111 1111 1111 1111 1111
这种情况最为严格,接收到的标示符必须每一位都得与过滤器中的标示符的每一位进行匹配,有一位不对报文就会被丢弃。
这个标示符匹配的工作是 CAN 模块内部硬件自动完成的
  

二、IdMask 库代码
本程序中,使用的软件代码是:
软件:

STM8S_StdPeriph_LibProjectSTM8S_StdPeriph_ExamplesCANCAN_Networking 路径下面的代码, 硬件STM8/128 EVAL 板子,上面的 MCU 位 STM8S208MBT6B ;
程序里面打开了接收的中断:
1.JPG
所以为了能够更有效的操作实践这一功能,我使用了:
2.webp.jpg

如上图的,CAN 总线的分析仪器 USB-CAN200 ;以及它的上位机:
在这里需要说明一点,
3.webp.jpg
将 R0+与 R0-相短接,则内部的 120 欧姆的电阻会被接入总线,不需要画蛇添足,在 R0+与 R0-之间自己再找一个 120 欧姆 的电阻外部接上!!!!

4.webp.jpg
在接收中断里面已经有现成的对标准桢结构;所以设置好,Idfliter 或者 Idmask 就可以;
5.webp.jpg
也就是上面的 这一段函数; 按照刚才的理解,
如果我的扩展 id 是 0x12345678 ;想只接收 0x12xxxxxx 的标识符号,那么是否填入
CAN_FilterID1 = 0x12 ;
CAN_FilterIDMask = 0xFF
就可以了呢? 本以为是这样,结果通过上位机发出去之后,led 板上的符号并没有变化;说明并没有接收到; 这是为什么呢?
三、分析

6.webp.jpg
所以对于扩展的 ID 号码它有 29 位,但是程序中设计的过滤器位 32 位,所以:
如果假设扩展 id 为 0x12345678 (0001,0010,0011,0100,0101,0110,0111,1000)
7.webp.jpg
因为假设的扩展 id 为 0x12345678,所以依次填入下面的表格:
8.webp.jpg

所以扩展 id 的顺序填入如上图所示意,这儿假设的:

RTR 位我们设置为 0 表示数据帧,IDE 位设置为 1 表示扩展 ID,因为我们的 ID 是 29 位的,所以 RTR = 0; IDE = 1;
再来看我们参考手册中,定义的 :

9.webp.jpg
将上面数据中的标示符号位再填入到 figure 的表过滤器中:
10.webp.jpg
所以可以看到颜色的顺序已经被打乱了, 如果要关心到具体的某一个比特位置;如果要过滤让它只接收 0x12xxxxxx 的表示符号; 这时候要根据它实际在 identify 中的位置去修改 idmask ; 前八个比特,对应的就是黄色和绿色的部分, 所以其他的颜色,可以都填 0 表示不需要关心,则这里填入:1 1 1 1 ,1 x x 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 ;所以填入到:
11.webp.jpg

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; //

如下图,测试通过;


12.webp.jpg
四、附录
在 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 的全称为“远程发送请求位(Remote Transmission Request BIT)”。 RTR 位在数据帧里必须为“显性”,而在远程帧里必须为“隐性”
  
扩展格式里,基本 ID 首先发送,其次是 IDE 位和 SRR 位。扩展 ID 的发送位与 SRR 位之后。
SRR 位(扩展格式)
SRR 的全称是“替代远程请求位(Substitute Remote Request BIT)”。
SRR 是一隐性位。它在扩展格式的标准帧 RTR 位位置,因此代替标准帧的 RTR 位。因此,标准帧与扩展帧的冲突是通过标 准帧优先于扩展帧这一途径得以解决的,扩展帧的基本 ID(参见以下的“扩展识别符”)如同标准帧的识别符。
IDE 位(扩展格式)
IDE 的全称是“识别符扩展位(Identifier Extension Bit)”
  
IDE 位属于:
- 扩展格式的仲裁场
- 标准格式的控制场
标准格式里的 IDE 位为“显性(逻辑 0)”,而扩展格式里的 IDE 位为“隐性”。
  
在标识符列表模式下,屏蔽寄存器当作标识符寄存器用。因此,使用 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 00010xc1
Cna_fxr2:0100 10010x49  //这里有个 RTR 位我们设置为 0 表示数据帧,IDE 位设置为 1 表示扩展 ID, Cna_fxr3:0100 00010x41

Cna_fxr4:1101 11100xDE

这时我们工作在标识符列表模式,identifier/Mask 的寄存器相当于 identifier 使用。
再将 0x1828A0EE 二进制的格数据组成如上图 mapping 所示的格式
Cna_fxr5:1100 00010xc1
Cna_fxr6:0100 10010x49  //这里有个 RTR 位我们设置为零表示数据帧,IDE 设置为 1 表示扩展 ID Cna_fxr7:0100 00010x41

Cna_fxr8:1101 11000xDC

以下是用库函数配置的程序小片段:
CAN_FilterNumber =CAN_FilterNumber_0;
//注意这是的模式是跟 IdMask 例不一样的
相信看到这是你对这两种工作模式有一定的了解了吧!。
好了,例子就说完了,8 位 16 位的位宽是相似的,和上面的分析是一样的。



更多回帖

发帖
×
20
完善资料,
赚取积分