STM32F103xx bxCAN的滤波机制

一、背景
    最近一个项目需要使用STM32F103xx实现CAN通信,而CAN总线的消息滤波在各个MCU上有不同机制,譬如,SJA1000为标识符位屏蔽滤波机制,NXP的LPC17xx系列为标识符列表查询机制等等,本篇就STM32F103xx的滤波机制做个简述。
    注:软件上使用的是ST提供的库函数。

二、正文
    STM32F103xx在滤波这方面确实很赞,同时集成了标识符位屏蔽滤波机制和标识符列表查询机制。
    --->标识符位屏蔽滤波机制:
        该机制既是对标识符相应位进行屏蔽,而实现该功能需要两个寄存器,     一个是标识符寄存器,一个是标识符屏蔽寄存器。
        以11位CAN标准帧ID为例,
        若标识符屏蔽寄存器对应第"0"位为"0",则接收到的信息ID的第"0"位不论是"0"或者"1"均可被通过验收。
        若标识符屏蔽寄存器对应第"0"位为"1",则接收到的信息ID的第"0"位一定要和标识符寄存器的第"0"位相同才可被验收。
        按此种法则,若接收到的信息ID与全部标识符屏蔽寄存器为"1"的位所对应的标识符寄存器一致,则信息被接收,同时产生接收中断。

    --->标识符列表查询机制
        该机制既是对接收到的标识符进行比对查询,而实现该功能仅需要一个寄存器,该寄存器保存的则是需要验收的标识符。
        同样,以11位CAN标准帧ID为例,
        在标识符寄存器中保存了几个信息ID,当从CAN总线上接收到信息后,CAN硬件会将该信息ID与标识符寄存器中的信息ID进行比对,     若相同,则被验收,产生接收中断,若比对失败,则该信息被丢弃,说明不是CPU需要的信息。

    按照以上的介绍,我们则可总结:
    --->若是需要精确验收几个信息,则使用标识符列表查询机制;
    --->若是需要验收一组信息,则使用标识符位屏蔽机制。

    说完了这两种滤波机制的远离,言归正传,STM32F103xx在非互联产品中,有14个位宽可调(16位/32位)的过滤器组,   ——至于什么是位宽,稍后再做解释——,每组过滤器由2个32位宽的寄存器组成(CAN_FxR0, CAN_FxR1)。
    过滤器组织框架图如下表:

如图所示,过滤器可根据FSCx位,选择为32位位宽模式或者16位位宽模式;然后根据FBMx来决定使用标识符位屏蔽模式还是标识符列表查询模式。(x代表是第几组过滤器)
    --->当为32位位宽,标识符屏蔽模式时,CAN_FxR1寄存器保存的是标识符,CAN_FxR2寄存器保存的是对应的标识符屏蔽位。
        注意,若是只需过滤标准帧,则CAN_FxR1的IDE位为1(标准帧),CAN_FxR2位为1(表示IDE位必须要为1,也即必须为标准帧)。
        标准帧标识符,以及其标准帧屏蔽位保存的位置均应该在这两个寄存器的最高11位!
    --->当为32位位宽,标识符列表模式时,CAN_FxR1寄存器保存的是第一组标识符,CAN_FxR2寄存器保存的是第二组标识符位
    --->当为16位位宽,标识符列表模式时,CAN_FxR1寄存器低16位保存的是第一组标识符,高16位保存的是第一组标识符屏蔽位;
        CAN_FxR2寄存器低16位保存的是第二组标识符,高16位保存的是第二组标识符屏蔽位。
    --->当为16位位宽,标识符列表模式时,CAN_FxR1寄存器低16位保存的是第一组标识符,高16位保存的是第二组标识符屏蔽位;
        CAN_FxR2寄存器低16位保存的是第三组标识符,高16位保存的是第四组标识符屏蔽。
    注:由于扩展帧有29位,所有若是需要过滤扩展帧信息,则必须使用32位位宽模式。

    就库函数设置滤波来做个示例:
    void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
    该库函数既是ST官方提供,根据结构体CAN_FilterInitStruct来设置CAN滤波,该结构体格式如下,
    typedef struct
    {
        /*  此处不要被"uint16_t CAN_FilterMaskIdHigh"这个名称给迷惑了,
         *  当过滤器工作在标识符屏蔽位模式时,这个名称很符合其意义。
         *  但当过滤器工作在标识符列表模式时,这个变量则是保存第二组标识符!
         */
        // 对应CAN_FxR1高16位
        uint16_t CAN_FilterIdHigh;
        // 对应CAN_FxR1低16位
        uint16_t CAN_FilterIdLow;
        // 对应CAN_FxR2高16位
        uint16_t CAN_FilterMaskIdHigh;
        // 对应CAN_FxR2高16位
        uint16_t CAN_FilterMaskIdLow;

        //对应哪一个过滤器组
        uint8_t CAN_FilterNumber;

        // 对应的CAN_FilterNumber过滤器模式选择(FM1R)
        /* 过滤器组(14组)的2个32位寄存器工作在标识符屏蔽位模式。
         * 过滤器组(14组)的2个32位寄存器工作在标识符列表模式。
         */
        uint8_t CAN_FilterMode;

        // 对应的CAN_FilterNumber过滤器位宽设置(CAN_FS1R)
        /* CAN_FilterScale_16bit: 两个16位过滤器
         * CAN_FilterScale_32bit: 单个32位过滤器
         */
        uint8_t CAN_FilterScale;

        // 报文被过滤后,存放的哪个FIFO中。(CAN_FFA1R)
        // 每个FIFO可以存放3条报文。
        /* CAN_Filter_FIFO0: 过滤器被关联到了FIFO0
         * CAN_Filter_FIFO1: 过滤器被关联到了FIFO1
         */
        uint16_t CAN_FilterFIFOAssignment;

        // 是否使能对应的CAN_FilterNumber滤波器
        FunctionalState CAN_FilterActivation;
    } CAN_FilterInitTypeDef;

    现在以实际配置一个32位标识符屏蔽位模式,过滤标识符0x123/0x121(最低位可为"0",为"1"。其它则被规定)为例:
    void Set_Filter(void) {
        // 声明该滤波结构体
        CAN_FilterInitTypeDef  CAN_FilterInitStructure;

        // 使用过滤器0
        CAN_FilterInitStructure.CAN_FilterNumber = 0;
        // 标识符屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
        // 使用32bit过滤器
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
        // 过滤器标识符0x123
        // 注意,标准帧放在最高的11位
        CAN_FilterInitStructure.CAN_FilterIdHigh=(0x123 << 5);
        CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
        // 过滤器屏蔽标识符最高10位全为"1",第11位为"0",即不做规定。
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFF8A;
        CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
        // 过滤器FIFO0指向过滤0,即过滤到合格的数据,中断应从FIFO0读取。
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
        /* 此处注意!!!,无论你是否需要使用过滤器,过滤器一定要被使能!否则无法被接收数据。
         * 若是不想使用过滤器,可将所有屏蔽位设置为"0",即全部不检测,但一定要被使能!!!
         */
        // 使能过滤器
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
        // 调用库函数
        CAN_FilterInit(&CAN_FilterInitStructure);
    }

三、参考文献
    本篇在研究STM32F103XX的CAN滤波机制过程中,在网上发现有位博主写的非常详细细致,也更加通俗易懂,有兴趣的可以移步参考,也非常感谢该博主的分享。
    参考链接:http://blog.csdn.net/flydream0/article/details/52317532

至此记录完毕

记录时间:2016年9月8日
记录地点:深圳WZ
时间: 2025-01-04 16:55:50

STM32F103xx bxCAN的滤波机制的相关文章

[转]第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV

仅供参考,还未运行程序,理解部分有误,请参考英文原版. 绿色部分非文章内容,是个人理解. 转载请注明:http://blog.csdn.net/raby_gyl/article/details/17471617 Chapter 4:Exploring Structure from  Motion Using OpenCV 在这一章,我们将讨论来至运动结构(Structure from Motion,SfM)的概念,或者从一个运动的相机拍摄到的图像中更好的推测提取出来的几何结构,使用OpenCV的

MLAA

MLAA全称是Morphological   Antialiasing 意为形态抗锯齿 是Intel推出的完全基于CPU处理的抗锯齿解决方案. 对于游戏厂商使用的MSAA抗锯齿技术不同,Intel最新推出的MLAA将跨越边缘像素的前景和背景色进行混合,用第2种颜色来填充该像素,从而更有效地改进图像边缘的变现效果,这就是MLAA技术. 常用的抗锯齿方法还有如SSAA(超级采样抗锯齿) MSAA(多重采样抗锯齿) CFAA(可编程过滤抗锯齿) MLAA采用光栅和光线追踪两种应用方式,没有提供硬件加速

opengl纹理映射总结

大概步骤: 1.创建纹理对象,并为他指定一个纹理. 2.确定纹理如何应用到每个像素上. 3.启用纹理贴图 4.绘制场景,提供纹理和几何坐标 过滤:由于我们提供的纹理图像很少能和最终的屏幕坐标形成对应,大小不同,所以需要设置过滤项目.允许我们进行插值或者匀和,指定放大缩小的函数.glTexParameter*(),使用过滤模式GL_NEAREST那么纹理单位最邻近的将被使用,GL_LINEAR那么就用2*2的包含纹理数据的数组加权组作为纹理; 命名纹理对象:glGenTexures(GLSize

Python爬虫|深入请求(四)常见的反爬机制以及应对方法

作者:David Qian 链接:https://zhuanlan.zhihu.com/p/21558661 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 大家好!我是厦门大学王亚南经济研究院的大一学生,今天将由我来为大家介绍一下常见的反爬机制以及应对方法. 注:非商业转载注明作者即可,商业转载请联系作者授权并支付稿费.本人已授权"维权骑士"网站(http://rightknights.com)对我在知乎发布文章的版权侵权行为进行追究与维权. ---

知物由学 | 基于DNN的人脸识别中的反欺骗机制

"知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物由学"希望通过一篇篇技术干货.趋势解读.人物思考和沉淀给你带来收获的同时,也希望打开你的眼界,成就不一样的你.当然,如果你有不错的认知或分享,也欢迎通过邮件([email protected])投稿. 以下是正文: 本文作者:ArturBa?maga,YND的AI专家. 想象一下,只需使用脸部即可解

ffmpeg滤波

ffmpeg中有很多已经实现好的滤波器,这些滤波器的实现位于libavfilter目录之下,用户需要进行滤波时,就是是调用这些滤波器来实现的.ffmpeg对于调用滤波器有一整套的调用机制. 基本结构 我们把一整个滤波的流程称为滤波过程.下面是一个滤波过程的结构 图中简要指示出了滤波所用到的各个结构体,各个结构体有如下作用: AVFilterGraph 用于统合这整个滤波过程的结构体. AVFilter 滤波器,滤波器的实现是通过AVFilter以及位于其下的结构体/函数来维护的. AVFilte

ffmpeg多输入滤波处理方式(framesync)

滤波也不总是单一的输入,也存在对多个输入流进行滤波的需求,最常见的就是对视频添加可视水印,水印的组成通常为原视频以及作为水印的图片或者小动画,在ffmpeg中可以使用overlay滤波器进行水印添加. 对于多视频流输入的滤波器,ffmpeg提供了一个名为framesync的处理方案.framesync为滤波器分担了不同线路的输入的帧同步任务,并为滤波器提供同步过后的帧,使得滤波器专注于滤波处理. Extend Mode 由于各个视频流可能长短不一,可能其实或者结束时间也不同,为了应对由此产生的各

常见的反爬机制及应对策略

1.Headers: 从用户的headers进行反爬是最常见的反爬策略,Headers是一种最常见的反爬机制Headers是一种区分浏览器行为和机器行为中最简单的方法,还有一些网站会对Referer (上级链接)进行检测 从而实现爬虫. 相应的解决措施:通过审查元素或者开发者工具获取相应的headers 然后把相应的headers 传输给python 的requests,这样就能很好地绕过. 2.IP 限制 一些网站会根据你的IP 地址访问的频率,次数进行反爬.也就是说如果你用单一的IP 地址访

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个