你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM8 CAN 总线的 IdMask 模式的讲解

[复制链接]
STMCU小助手 发布时间:2022-2-12 18:34
前言
学习了 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_Filter xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
CAN_FilterMask 0000 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_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 二进制码: 0000 0000 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 ;
程序里面打开了接收的中断:

{D2~8LQK~21G2~N`KJ2(S}B.png

所以为了能够更有效的操作实践这一功能,我使用了:

KTU2@V]{GU7XOJID3K3`$[E.png

如上图的,CAN 总线的分析仪器 USB-CAN200 ;以及它的上位机:
在这里需要说明一点,

2($FIM4[O8P}]8LQIHC`0MV.png

将 R0+与 R0-相短接,则内部的 120 欧姆的电阻会被接入总线,不需要画蛇添足,在 R0+与 R0-之间自己再找一个 120 欧姆的电阻外部接上!!!!

SGJ)3GLE@$_TMSJS6F2@N)8.png

在接收中断里面已经有现成的对标准桢结构;所以设置好,Idfliter 或者 Idmask 就可以;

K%LSRP[(BF92`N{`G0]2]IH.png

也就是上面的 这一段函数;
按照刚才的理解,
如果我的扩展 id 是 0x12345678 ;想只接收 0x12xxxxxx 的标识符号,那么是否填入
CAN_FilterID1 = 0x12 ;
CAN_FilterIDMask = 0xFF
就可以了呢? 本以为是这样,结果通过上位机发出去之后,led 板上的符号并没有变化;说明并没有接收到;
这是为什么呢?


三、分析

H4RDWKTN6%_83M(DZWE712W.png
所以对于扩展的 ID 号码它有 29 位,但是程序中设计的过滤器位 32 位,所以:
如果假设扩展 id 为 0x12345678 (0001,0010,0011,0100,0101,0110,0111,1000)

LX8%VQ(G1W(JMK{H%_SLC.png

所以扩展 id 的顺序填入如上图所示意,这儿假设的:
RTR 位我们设置为 0 表示数据帧,IDE 位设置为 1 表示扩展 ID,因为我们的 ID 是 29 位的,所以 RTR = 0; IDE = 1;
再来看我们参考手册中,定义的 :

G%FLMO`5ZBT(RKN76QKEN.png

将上面数据中的标示符号位再填入到 figure 的表过滤器中:

U`O[JTG(7QV{FVWEPS9FP5L.png

所以可以看到颜色的顺序已经被打乱了,
如果要关心到具体的某一个比特位置;如果要过滤让它只接收 0x12xxxxxx 的表示符号;
这时候要根据它实际在 identify 中的位置去修改 idmask ; 前八个比特,对应的就是黄色和绿色的部分,
所以其他的颜色,可以都填 0 表示不需要关心,则这里填入:1 1 1 1 ,1 x x x,我们这里 填入 0xF8 ;
即:
  1. CAN_FilterID1=0x91;
  2. CAN_FilterID2=0x00;
  3. CAN_FilterID3=0x00;
  4. CAN_FilterID4=0x00;
  5. CAN_FilterIDMask1=0xF8; //0
  6. CAN_FilterIDMask2=0x00; //0
  7. CAN_FilterIDMask3=0x00; //0x0
  8. CAN_FilterIDMask4=0x00; //
复制代码

同理,对于下面的配置是只接收标准 id= 0x321(0011,0010,0001)的 ID(也是 32 位过滤器),
因为也是数据帧,所以 RTR = 0,标准的 id,所以 IDE = 0 ;所以填入到:

XX3S$KK_LH6P9@L8CPGUQ8G.png

  1. CAN_FilterID1=0x64;
  2. CAN_FilterID2=0x20;
  3. CAN_FilterID3=0x00;
  4. CAN_FilterID4=0x00;
  5. CAN_FilterIDMask1=0xFF; //0
  6. CAN_FilterIDMask2=0xE0; //0
  7. CAN_FilterIDMask3=0x0; //0x0
  8. CAN_FilterIDMask4=0x0; //
复制代码

如下图,测试通过;

3P%%M6(**KV7UB]S5_TT_T.png

四、附录

在 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 0001 0xc1
  Cna_fxr2:0100 1001 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:0100 1001 0x49 //这里有个 RTR 位我们设置为零表示数据帧,IDE 设置为 1 表示扩展 ID
  Cna_fxr7:0100 0001 0x41
  Cna_fxr8:1101 1100 0xDC
  以下是用库函数配置的程序小片段:
  CAN_FilterNumber =CAN_FilterNumber_0;
  //注意这是的模式是跟 IdMask 例不一样的
  1.   CAN_FilterMode =CAN_FilterMode_IdList;
  2.   CAN_FilterScale =CAN_FilterScale_32Bit;
  3.   CAN_FilterID1=0xc1;
  4.   CAN_FilterID2=0x49;
  5.   CAN_FilterID3=0x41;
  6.   CAN_FilterID4=0xde;
  7.   CAN_FilterIDMask1=0xc1;
  8.   CAN_FilterIDMask2=0x49;
  9.   CAN_FilterIDMask3=0x41;
  10.   CAN_FilterIDMask4=0xdc;
复制代码

  相信看到这是你对这两种工作模式有一定的了解了吧!。
  好了,例子就说完了,8 位 16 位的位宽是相似的,和上面的分析是一样的;。

收藏 评论0 发布时间:2022-2-12 18:34

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版