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

【经验分享】STM32之CAN通讯接收过滤器过滤分析

[复制链接]
STMCU小助手 发布时间:2022-1-20 20:56
一、前言
学习了CAN通讯,底层的东东CAN控制器已经帮你处理完成,也就是CAN通讯协议已经做好,你按协议格式往对应的位扔数据发送就好,所以使用CAN通讯,我们只需要去关心制定发送的数据间的协议,也就是给每个数据加上有标识符的协议。如下图所示的CAN通讯发送数据的数据帧,Arbitration Field即是具有优先级的标识ID,Data Field即是要发送的数据,Arbitration Field、Data Field就是我们关注的重点,因为CAN通讯协议里边这些发送出来的标识ID并不代表节点的地址,数据是以广播形式发送出来,每个节点都是可以接收,至于接收到的数据是不是想要的?就需要对这些标识的ID进行筛选和过滤,再去提取数据。
二、CAN 通讯接收过滤器的分析
首先我们看下要配置发送数据的结构,如下所示。我们发送的Arbitration Field标识即是CanTxMsg.StdId,接收则会先过滤标识ID过滤处理后,再去提取发送的的CanTxMsg.Data。如果不是设定的标识ID,接收则不会去读取数据,到底接收方是怎样去过滤处理的。

  1. typedef struct
  2. {
  3.   uint32_t StdId;    //11位 标准帧ID即Arbitration Field
  4.   uint32_t ExtId;    //29位 扩展帧ID
  5.   uint8_t IDE;       //1位  O:标准帧,1:扩展帧
  6.   uint8_t RTR;       //1位  0:数据帧,1:远程帧
  7.   uint8_t DLC;       //4位  发送的数据的长度
  8.   uint8_t Data[8];   //8位  发送的数据即Data Field
  9. } CanTxMsg;
复制代码

因为STM32在非互联网型产品中CAN控制器提供了14个位宽可变、可配置的过滤器组(13~0),每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成,而1个过滤器组的位宽设置可以分成四种工作模式,工作模式取决于两个寄存器FBMx,FSCx的设置,如下图所示:

1100486-20170306184647656-1740544022.png


看到过滤器的四种工作模式,工作模式中标识符屏蔽和列表模式,如何去理解,举个例子,假如我们发送的标识IDCanTxMsg.StdId是0x000~0x00f,接收过滤先用标识符屏蔽模式来过滤标识的ID,如下所示:
  1. <font color="rgb(255, 0, 0)">ID  :</font>     000 0000 0000 <font color="rgb(163, 21, 21)">xxxx</font>               <div><font color="rgb(163, 21, 21)">屏蔽</font> <font color="rgb(163, 21, 21)">:</font>     111 1111 1111 0000   </div>
复制代码

x代表0或者1都是可以通过,0000到1111的任意组合,这样就可以过滤出0x000~0x00f的数据的,所以屏蔽的意思就是让某个范围的标识符ID可以通过,目的是过滤出一组标志符。那么如果想过滤出一个数据0x003,用标识符屏蔽模式实现方式如下,
  1. <div><font color="rgb(255, 0, 0)">ID  :</font>     000 0000 0000 0011               </div><div><font color="rgb(163, 21, 21)">屏蔽</font> <font color="rgb(163, 21, 21)">:</font>     111 1111 1111 1111   </div>
复制代码


如果接收过滤使用标识符列表模式来过滤标识ID,如下所示,
  1. <div><font color="rgb(255, 0, 0)">ID  :</font>    000 0000 0001  </div><div><font color="rgb(255, 0, 0)">ID  :</font>    000 0000 0010</div>
复制代码


这种模式只能过滤出两个ID,即0x001,0x002,所以列表的意思就是要去罗列想要的标识ID后跟发送过来的CanTxMsg.StdId进行校对,如果是则去接收数据,不是则过滤掉数据,标识符列表模式目的是过滤出一个标志符ID。
三、CAN 接收过滤器的四种工作模式的程序配置
1、32位标识符屏蔽模式

1100486-20170306174607938-1478027373.png

假如要发送的标示符IDCanTxMsg.StdId范围为0x010~0x01f
  1. ID      : 0000 001x xxx0 0000 0000 0000 0000 0000  //分别对应CAN_FxR1高16位、CAN_FxR1低16位
  2. 屏蔽    : 1111 1110 0001 1111 1111 1111 1111 1111  //分别对应CAN_FxR2高16位、CAN_FxR2低16位
复制代码


程序配置如下:
  1. CAN_RxFilerconfig(0,CANRX32IDMASK);                                      //32位标识符屏蔽模式
  2. void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
  3. {
  4.   CAN_FilterInitTypeDef          CAN_FilterInitStructure;
  5.    
  6.    CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;                       //过滤器号0~13可选
  7.    if(FilterMode==CANRX32IDMASK)
  8.    {
  9.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  10.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  11.    }
  12.    else if(FilterMode==CANRX32IDLIST)
  13.    {
  14.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  15.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  16.    }
  17.    else if(FilterMode==CANRX16IDMASK)
  18.    {
  19.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  20.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  21.    }
  22.    else if(FilterMode==CANRX16IDLIST)
  23.    {
  24.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  25.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  26.    }
  27.     //标识符寄存器FxR1
  28.    CAN_FilterInitStructure.CAN_FilterIdHigh=0x010<<5;                  //32位ID,高16位
  29.    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;                     //低16位
  30.    //屏蔽寄存器FxR2
  31.    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;                //32位MASK,高16位
  32.    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;                 //低16位
  33.        
  34.    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //过滤器0关联到FIFO0
  35.    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //激活过滤器0

  36.    CAN_FilterInit(&CAN_FilterInitStructure);                                       //滤波器初始化
  37. }
复制代码



2、32位标识符列表模式

1100486-20170308163452531-1730489200.png

假如要发送的标示符IDCanTxMsg.StdId为0x011和0x012两个。
  1. ID      : 0000 0010 0010 0000 0000 0000 0000 0000  //分别对应CAN_FxR1高16位、CAN_FxR1低16位  //0x011
  2. 屏蔽    : 0000 0010 0100 1111 1111 1111 1111 1111  //分别对应CAN_FxR2高16位、CAN_FxR2低16位  //0x012
复制代码

程序配置如下:
  1. CAN_RxFilerconfig(0,CANRX32IDLIST);                                      //32位标识符列表模式
  2. void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
  3. {
  4.   CAN_FilterInitTypeDef          CAN_FilterInitStructure;
  5.    
  6.    CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;                       //过滤器号0~13可选
  7.    if(FilterMode==CANRX32IDMASK)
  8.    {
  9.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  10.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  11.    }
  12.    else if(FilterMode==CANRX32IDLIST)
  13.    {
  14.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  15.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  16.    }
  17.    else if(FilterMode==CANRX16IDMASK)
  18.    {
  19.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  20.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  21.    }
  22.    else if(FilterMode==CANRX16IDLIST)
  23.    {
  24.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  25.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  26.    }
  27.     //标识符寄存器FxR1
  28.    CAN_FilterInitStructure.CAN_FilterIdHigh=0x011<<5;                  //32位ID,高16位
  29.    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;                     //低16位
  30.    //屏蔽寄存器FxR2
  31.    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x012<<5;              //32位MASK,高16位
  32.    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;                 //低16位
  33.        
  34.    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //过滤器0关联到FIFO0
  35.    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //激活过滤器0

  36.    CAN_FilterInit(&CAN_FilterInitStructure);                                       //滤波器初始化
  37. }
复制代码


3、16位标识符屏蔽模式

1100486-20170308164239641-1269194157.png

假如要发送的标示符IDCanTxMsg.StdId范围为0x0100x01f,0x0000x00f。
  1. ID      : 0000 001x xxx0 0000  //分别对应CAN_FxR1低16位  CAN_FilterIdLow
  2. 屏蔽    : 1111 1110 0001 1111  //分别对应CAN_FxR1高16位  CAN_FilterIdHigh

  3. ID      : 0000 000x xxx0 0000  //分别对应CAN_FxR2低16位  CAN_FilterMaskIdLow
  4. 屏蔽    : 1111 1110 0001 1111  //分别对应CAN_FxR2高16位  CAN_FilterMaskIdHigh
复制代码

程序配置如下:
  1. CAN_RxFilerconfig(0,CANRX16IDMASK);                                      //16位标识符屏蔽模式
  2. void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
  3. {
  4.   CAN_FilterInitTypeDef          CAN_FilterInitStructure;
  5.    
  6.    CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;                       //过滤器号0~13可选
  7.    if(FilterMode==CANRX32IDMASK)
  8.    {
  9.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  10.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  11.    }
  12.    else if(FilterMode==CANRX32IDLIST)
  13.    {
  14.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  15.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  16.    }
  17.    else if(FilterMode==CANRX16IDMASK)
  18.    {
  19.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  20.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  21.    }
  22.    else if(FilterMode==CANRX16IDLIST)
  23.    {
  24.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  25.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  26.    }
  27.     //标识符寄存器FxR1
  28.    CAN_FilterInitStructure.CAN_FilterIdHigh=0xfe1f;                    //32位ID,高16位
  29.    CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;                   //低16位
  30.    //屏蔽寄存器FxR2
  31.    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;                //32位MASK,高16位
  32.    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x000<<5;               //低16位
  33.        
  34.    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //过滤器0关联到FIFO0
  35.    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //激活过滤器0

  36.    CAN_FilterInit(&CAN_FilterInitStructure);                                       //滤波器初始化
  37. }
复制代码


4、16位标识符列表模式

1100486-20170308171618219-1716149981.png

假如要发送的标示符IDCanTxMsg.StdId 有0x010,0x01f,0x001,0x00f四个。
  1. ID      : 0000 0010 0000 0000  //分别对应CAN_FxR1低16位  CAN_FilterIdLow  //0x010
  2. ID      : 0000 0011 1110 0000  //分别对应CAN_FxR1高16位  CAN_FilterIdHigh //0x01f

  3. ID      : 0000 0000 0010 0000  //分别对应CAN_FxR2低16位  CAN_FilterMaskIdLow //0x001
  4. ID      : 0000 0001 1110 0000  //分别对应CAN_FxR2高16位  CAN_FilterMaskIdHigh //0x00f
复制代码

程序配置如下:
  1. CAN_RxFilerconfig(0,CANRX16IDLIST);                                      //16位标识符列表模式
  2. void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
  3. {
  4.   CAN_FilterInitTypeDef          CAN_FilterInitStructure;
  5.    
  6.    CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;                       //过滤器号0~13可选
  7.    if(FilterMode==CANRX32IDMASK)
  8.    {
  9.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  10.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  11.    }
  12.    else if(FilterMode==CANRX32IDLIST)
  13.    {
  14.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  15.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32位宽
  16.    }
  17.    else if(FilterMode==CANRX16IDMASK)
  18.    {
  19.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;            //标识符屏蔽模式
  20.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  21.    }
  22.    else if(FilterMode==CANRX16IDLIST)
  23.    {
  24.      CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;            //标识符列表模式
  25.      CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16位宽
  26.    }
  27.     //标识符寄存器FxR1
  28.    CAN_FilterInitStructure.CAN_FilterIdHigh=0x01f<<5;                  //32位ID,高16位
  29.    CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;                   //低16位
  30.    //屏蔽寄存器FxR2
  31.    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00f<<5;              //32位MASK,高16位
  32.    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x001<<5;               //低16位
  33.        
  34.    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //过滤器0关联到FIFO0
  35.    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //激活过滤器0

  36.    CAN_FilterInit(&CAN_FilterInitStructure);                                       //滤波器初始化
  37. }
复制代码


1100486-20170303180750376-74083783.png
收藏 评论0 发布时间:2022-1-20 20:56

举报

0个回答

所属标签

相似分享

官网相关资源

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