STM32之CAN通讯接收过滤器过滤分析
一、前言 学习了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,接收则不会去读取数据,到底接收方是怎样去过滤处理的。
typedef struct
{
uint32_t StdId;
//11位 标准帧ID即Arbitration Field
uint32_t ExtId;
//29位 扩展帧ID
uint8_t IDE;
//1位O:标准帧,1:扩展帧
uint8_t RTR;
//1位0:数据帧,1:远程帧
uint8_t DLC;
//4位发送的数据的长度
uint8_t Data[8];
//8位发送的数据即Data Field
} CanTxMsg;
因为STM32在非互联网型产品中CAN控制器提供了14个位宽可变、可配置的过滤器组(13~0),每个过滤器组x由2个32位寄存器,CAN_FxR0和CAN_FxR1组成,而1个过滤器组的位宽设置可以分成四种工作模式,工作模式取决于两个寄存器
FBMx
,FSCx
的设置,如下图所示:文章图片
看到过滤器的四种工作模式,工作模式中标识符
屏蔽
和列表
模式,如何去理解,举个例子,假如我们发送的标识IDCanTxMsg.StdId
是0x000~0x00f,接收过滤先用标识符屏蔽模式
来过滤标识的ID,如下所示: ID:000 0000 0000 xxxx
屏蔽 :111 1111 1111 0000
x代表0或者1都是可以通过,0000到1111的任意组合,这样就可以过滤出0x000~0x00f的数据的,所以
屏蔽
的意思就是让某个范围的标识符ID可以通过,目的是过滤出一组标志符
。那么如果想过滤出一个数据0x003,用标识符屏蔽模式
实现方式如下, ID:000 0000 0000 0011
屏蔽 :111 1111 1111 1111
如果接收过滤使用
标识符列表模式
来过滤标识ID,如下所示, ID:000 0000 0001
ID:000 0000 0010
这种模式只能过滤出两个ID,即0x001,0x002,所以
列表
的意思就是要去罗列想要的标识ID
后跟发送过来的CanTxMsg.StdId
进行校对,如果是则去接收数据,不是则过滤掉数据,标识符列表模式目的是过滤出一个标志符ID
。三、CAN 接收过滤器的四种工作模式的程序配置 1、32位标识符屏蔽模式
文章图片
假如要发送的标示符ID
CanTxMsg.StdId
范围为0x010~0x01fID: 0000 001x xxx0 0000 0000 0000 0000 0000//分别对应CAN_FxR1高16位、CAN_FxR1低16位
屏蔽: 1111 1110 0001 1111 1111 1111 1111 1111//分别对应CAN_FxR2高16位、CAN_FxR2低16位
程序配置如下:
CAN_RxFilerconfig(0,CANRX32IDMASK);
//32位标识符屏蔽模式
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
CAN_FilterInitTypeDefCAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;
//过滤器号0~13可选
if(FilterMode==CANRX32IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX32IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX16IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
else if(FilterMode==CANRX16IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
//标识符寄存器FxR1
CAN_FilterInitStructure.CAN_FilterIdHigh=0x010<<5;
//32位ID,高16位
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
//低16位
//屏蔽寄存器FxR2
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;
//32位MASK,高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;
//低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//激活过滤器0CAN_FilterInit(&CAN_FilterInitStructure);
//滤波器初始化
}
2、32位标识符列表模式
文章图片
假如要发送的标示符ID
CanTxMsg.StdId
为0x011和0x012两个。ID: 0000 0010 0010 0000 0000 0000 0000 0000//分别对应CAN_FxR1高16位、CAN_FxR1低16位//0x011
屏蔽: 0000 0010 0100 1111 1111 1111 1111 1111//分别对应CAN_FxR2高16位、CAN_FxR2低16位//0x012
程序配置如下:
CAN_RxFilerconfig(0,CANRX32IDLIST);
//32位标识符列表模式
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
CAN_FilterInitTypeDefCAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;
//过滤器号0~13可选
if(FilterMode==CANRX32IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX32IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX16IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
else if(FilterMode==CANRX16IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
//标识符寄存器FxR1
CAN_FilterInitStructure.CAN_FilterIdHigh=0x011<<5;
//32位ID,高16位
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
//低16位
//屏蔽寄存器FxR2
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x012<<5;
//32位MASK,高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;
//低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//激活过滤器0CAN_FilterInit(&CAN_FilterInitStructure);
//滤波器初始化
}
3、16位标识符屏蔽模式
文章图片
假如要发送的标示符ID
CanTxMsg.StdId
范围为0x010~0x01f,0x000~0x00f。ID: 0000 001x xxx0 0000//分别对应CAN_FxR1低16位CAN_FilterIdLow
屏蔽: 1111 1110 0001 1111//分别对应CAN_FxR1高16位CAN_FilterIdHighID: 0000 000x xxx0 0000//分别对应CAN_FxR2低16位CAN_FilterMaskIdLow
屏蔽: 1111 1110 0001 1111//分别对应CAN_FxR2高16位CAN_FilterMaskIdHigh
程序配置如下:
CAN_RxFilerconfig(0,CANRX16IDMASK);
//16位标识符屏蔽模式
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
CAN_FilterInitTypeDefCAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;
//过滤器号0~13可选
if(FilterMode==CANRX32IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX32IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX16IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
else if(FilterMode==CANRX16IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
//标识符寄存器FxR1
CAN_FilterInitStructure.CAN_FilterIdHigh=0xfe1f;
//32位ID,高16位
CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;
//低16位
//屏蔽寄存器FxR2
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;
//32位MASK,高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x000<<5;
//低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//激活过滤器0CAN_FilterInit(&CAN_FilterInitStructure);
//滤波器初始化
}
4、16位标识符列表模式
文章图片
假如要发送的标示符ID
CanTxMsg.StdId
有0x010,0x01f,0x001,0x00f四个。ID: 0000 0010 0000 0000//分别对应CAN_FxR1低16位CAN_FilterIdLow//0x010
ID: 0000 0011 1110 0000//分别对应CAN_FxR1高16位CAN_FilterIdHigh //0x01fID: 0000 0000 0010 0000//分别对应CAN_FxR2低16位CAN_FilterMaskIdLow //0x001
ID: 0000 0001 1110 0000//分别对应CAN_FxR2高16位CAN_FilterMaskIdHigh //0x00f
程序配置如下:
CAN_RxFilerconfig(0,CANRX16IDLIST);
//16位标识符列表模式
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
CAN_FilterInitTypeDefCAN_FilterInitStructure;
CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;
//过滤器号0~13可选
if(FilterMode==CANRX32IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX32IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
//32位宽
}
else if(FilterMode==CANRX16IDMASK)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
//标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
else if(FilterMode==CANRX16IDLIST)
{
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;
//标识符列表模式
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
//16位宽
}
//标识符寄存器FxR1
CAN_FilterInitStructure.CAN_FilterIdHigh=0x01f<<5;
//32位ID,高16位
CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;
//低16位
//屏蔽寄存器FxR2
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00f<<5;
//32位MASK,高16位
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x001<<5;
//低16位CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;
//过滤器0关联到FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
//激活过滤器0CAN_FilterInit(&CAN_FilterInitStructure);
//滤波器初始化
}
by 羊羊得亿
2017-02-24 ShenZhen
【STM32之CAN通讯接收过滤器过滤分析】转载于:https://www.cnblogs.com/yangxuli/p/6497786.html
推荐阅读
- PMSJ寻平面设计师之现代(Hyundai)
- 太平之莲
- 闲杂“细雨”
- 七年之痒之后
- 深入理解Go之generate
- 由浅入深理解AOP
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 生活随笔|好天气下的意外之喜
- 感恩之旅第75天
- python学习之|python学习之 实现QQ自动发送消息