打印
[应用相关]

STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法

[复制链接]
3971|45
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法
沙发
東南博士|  楼主 | 2018-9-17 14:09 | 只看该作者
1. 前言
bxCAN是STM32系列最稳定的IP核之一,无论有哪个新型号出来,这个IP核基本未变,可见这个IP核的设计是相当成熟的。本文所讲述的内容属于这个IP核的一部分,掌握了本文所讲内容,就可以很方便地适用于所有STM32系列中包含bxCAN外设的型号。有关bxCAN的过滤器部分的内容在参考手册中往往看得“不甚明白“,本文就过滤器的4种工作模式进行详细讲解并使用具体的代码进行演示,这些代码都进行过实测验证通过的,希望能给读者对于bxCAN过滤器有一个清晰的理解。

使用特权

评论回复
板凳
東南博士|  楼主 | 2018-9-17 14:09 | 只看该作者
2.1.   为什么要过滤器?
在这里,我们可以将CAN总线看成一个广播消息通道,上面传输着各种类型的消息,好比报纸,有体育新闻,财经新闻,政治新闻,还有军事新闻,每个人都有自己的喜好,不一定对所有新闻都感兴趣,因此,在看报纸的时候,一般人都是只看自己感兴趣的那类新闻,而过滤掉其他不感兴趣的内容。那么我们一般是怎么过滤掉那些不感兴趣的内容的呢?下面有两种方法来实现这个目的:

使用特权

评论回复
地板
東南博士|  楼主 | 2018-9-17 14:09 | 只看该作者
第一种方法:

         每次看报纸时,你都看下每篇**的标题,如果感兴趣则继续看下去,如果不感兴趣,则忽略掉。

使用特权

评论回复
5
東南博士|  楼主 | 2018-9-17 14:10 | 只看该作者
第二种方法:

         你告诉邮递员,你只对财经新闻感兴趣,请只将财经类报纸送过来,其他的就不要送过来了,就这样,你看到的内容必定是你感兴趣的财经类新闻。

上面那种方法好呢?很明显,第二种方法是最好的,因为你不用自己每次判断哪些新闻内容是你感兴趣的,可以免受“垃圾”新闻干扰,从而可以节省时间忙其他事。bxCAN的过滤器就是采用上述第二种方法,你只需要设置好你感兴趣的那些CAN报文ID,那么MCU就只能收到这些CAN报文,是从硬件上过滤掉,完全不需要软件参与进来,从而节省了大大节省了MCU的时间,可以更加专注于其他事务,这个就是bxCAN过滤器的意义所在。

使用特权

评论回复
6
東南博士|  楼主 | 2018-9-17 14:11 | 只看该作者
2.2.   两种过滤模式(列表模式与掩码模式)
假设我们是bxCAN这个IP的设计者,现在由我们来设计过滤器,那么我们该如何设计呢?

首先我们是不是很快就会想到只要准备好一张表,把我们需要关注的所有CAN报文ID写上去,开始过滤的时候只要对比这张表,如果接收到的报文ID与表上的相符,则通过,如果表上没有,则不通过,这个就是简单的过滤方案。恭喜你!bxCAN过滤器的列表模式采用的就是这种方案。

使用特权

评论回复
7
東南博士|  楼主 | 2018-9-17 14:11 | 只看该作者
这种列表方案有点缺陷,即如果我们只关注一个报文ID,则需要往列表中写入这个ID,如果需要关注两个,则需要写入两个报文ID,如果需要关注100个,则需要写入100个,如果需要1万个,那么需要写入1万个,可问题是,有这个大的列表供我们使用吗?大家都知道,MCU上的资源是有限的,不可能提供1万个或更多,甚至100个都嫌多。非常明显,这种列表的方式受到列表容量大小的限制,实际上,bxCAN的一个过滤器若工作在列表模式下,scale为32时,每个过滤器的列表只能写入两个报文ID,若scale为16时,每个过滤器的列表最多可写入4个CAN ID,由此可见,MCU的资源是非常非常有限的,并不能任我们随心所欲。因此,我们需要考虑另外一种替代方案,这种方案应该不受到数量限制。

使用特权

评论回复
8
東南博士|  楼主 | 2018-9-17 14:11 | 只看该作者
下面假设我们是古时候一座城镇的守卫,城主要求只有1156年出生的人才可以进城,我们又该如何执行呢?假设古时候的人也有类似今天的身份*(...->_<-…),大家都知道,身份份证号码中有4位是表示出生年月,如下图:

使用特权

评论回复
9
東南博士|  楼主 | 2018-9-17 14:12 | 只看该作者
如上图,身份*中第7~10这4位数表示的是出生年份,那么,我们可以这么执行:

检查想要进城的所有人的身份*号码的第7~10位数字,如果这个数字依次为1156则可以进入,否则则不可以,至于身份*号码的其他位则完全不关心。假如过几天城主放宽进城条件为只要是1150年~1160前的人都可以进城,那么,我们就可以只关注身份*号码的第7~9这3位数是否为115就可以了,对不对?这样一来,我们就可以非常完美地执行城主的要求了。

使用特权

评论回复
10
東南博士|  楼主 | 2018-9-17 14:31 | 只看该作者
再变下,假设现在使用机器来当守卫,不再是人来执行这个“筛选”工作。机器是死的,没有人那么灵活,那么机器又该如何执行呢?

对于机器来说,每一步都得细化到机器可以理解的程度,于是我们可以作如下细化:

第一步:获取想进城的人的身份*号码

第二步:只看获取到身份*的第7~9位,其他位忽略

第三步:将忽略后的结果与1156进行比较

第四步:比较结果相同则通过,不同则不能通过

这种方式,我们称之为掩码模式。

使用特权

评论回复
11
東南博士|  楼主 | 2018-9-17 14:31 | 只看该作者
2.3.   验证码与屏蔽码
仔细查看上面4个步骤,这不就是C代码中的if语句吗?如下:

if( x & y ==z) //x表示待检查身份*号码,y表示只关注第7~9位的屏蔽码,Z则为1156,这里叫做验证码
{
        //可以通过
}
else
{
        //不可以通过
}

使用特权

评论回复
12
東南博士|  楼主 | 2018-9-17 14:32 | 只看该作者
对于机器来说,我们要为它准备好两张纸片,一片写上屏蔽码,另一片纸片写上验证码,屏蔽码上相应位为1时,表示此位需要与验证码对应位进行比较,反之,则表示不需要。机器在执行任务的时候先将获取的身份*号码与屏蔽码进行“与”操作,再将结果与验证码的进行比较,根据判断是否相同来决定是否通过。整个判别流程如下所示:

使用特权

评论回复
13
東南博士|  楼主 | 2018-9-17 14:32 | 只看该作者
从上图可以很容易地理解屏蔽码与验证码的含义,这样一来,能通过的结果数量就完全取决于屏蔽码,设得宽,则可以通过的多(所有位为0,则不过任何过滤操作,则谁都可以通过),设得窄,则通过的少(所有位设为1,则只有一个能通过)。那么知道这个有什么用呢?因为bxCAN的过滤器的掩码模式就是采用这种方式,在bxCAN中,分别采用了两个寄存器(CAN_FiR1,CAN_FiR2)来存储屏蔽码与验证码,从而实现掩码模式的工作流程的。这样,我们就知道了bxCAN过滤器的掩码模式的大概工作原理。

使用特权

评论回复
14
東南博士|  楼主 | 2018-9-17 14:33 | 只看该作者
我们得注意到,采用掩码模式的方式并不能精确的对每一个ID进行过滤,打个比方,还是采用之前的守卫的例子,假如城主要求只有1150~1158年出生的人能通过,那么,若我们还是才用掩码模式,那么掩码就设为第7~9位为”1”,对应的,验证码的7~9位分别为”115”,这样就可以了。但是,仔细一想,出生于1159的人还是可以通过,是不是?但总体来说,虽然没有做到精确过滤,但我们还是能做到大体过滤的,而这个就是掩码模式的缺点了。在实际应用时,取决于需求,有时我们会同时使用到列表模式和掩码模式,这都是可能的。

使用特权

评论回复
15
東南博士|  楼主 | 2018-9-17 14:34 | 只看该作者
列表模式与掩码模式的对比
综合之前所述,下面我们来对比一下列表模式与掩码模式这两种模式的优缺点。

使用特权

评论回复
16
東南博士|  楼主 | 2018-9-17 14:34 | 只看该作者
2.5.   标准CAN ID与扩展CAN ID
1986 年德国电气商BOSCH公司开发出面向汽车的CAN 通信协议,刚开始的时候,CAN ID定义为11位,我们称之为标准格式,ISO11898-1标准中CAN的基本格式如下图所示:

使用特权

评论回复
17
東南博士|  楼主 | 2018-9-17 14:34 | 只看该作者
标准CAN ID存放在上图ID18~ID28中,共11位。随着工业发展,后来发现11位的CAN ID已经不够用,于是就增加了18位,扩展CAN ID到29位,如下图所示:

使用特权

评论回复
18
東南博士|  楼主 | 2018-9-17 14:35 | 只看该作者
从上图对比扩展CAN报文与标准CAN报文,发现在仲裁域部分,扩展CAN报文的CAN ID包含了base Identifier与extension Identifier,即基本ID与扩展ID,而标准CAN报文的CAN ID部分只包含基本ID,扩展ID(ID0~ID17)被放在基本ID的右方,也就是说,属于低位。知道这些有什么用呢?至少我们可以得到这两条信息:

标准ID一般小于或等于<=0x7FF(11位),只包含基本ID。
对于扩展CAN的低18位为扩展ID,高11位为基本ID。
例如标准CAN ID 0x7E1,二进制展开为0b 0[111 1110 0001] ,只有中括号内的11位才有效,其全部是基本ID。

使用特权

评论回复
19
東南博士|  楼主 | 2018-9-17 14:35 | 只看该作者
再例如扩展CAN ID 0x1835f107,二进制展开为0b 000[1 1000 0011 10][01 11110001 0000 0111],只有红色中括号和绿色中括号内的位才有效,总共29位,左边红色中括号中的11位为基本ID,右边绿色中括号内的18位为扩展ID,请记住这个信息!知道这个之后,我们可以很方便地将一个CANID拆分成基本ID和扩展ID,这个也将在后续的内容中多次用到,再次留意一下,扩展ID是位于基本ID的右方,在扩展CAN ID的构成中,扩展ID位于低18位,而基本ID位于高11位,于是要获取一个扩展CANID的基本ID,就只需要将这个CANID右移18位(这种算法后续将多次用到,请务必记住!)。

使用特权

评论回复
20
東南博士|  楼主 | 2018-9-17 14:36 | 只看该作者
前面已经介绍了过滤器的列表模式与掩码模式,以及掩码模式下的屏蔽码与验证码的含义,还介绍了标准CAN ID与扩展CAN ID的组成部分。现在我们终于要站在bxCAN的角度来分析其过滤方案。

首先过滤模式分列表模式和掩码模式,因此,对于没有过滤器,我们需要这么一个位来标记,用户可以通过设置这个位来标记他到底是想要这个过滤器工作在列表模式下还是掩码模式,于是,这个表示过滤模式的位就定义在CAN_FM1R寄存器中的FBMx位上,如下图:

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

382

主题

6081

帖子

34

粉丝