打印
[应用相关]

谈STM32的CAN过滤器

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

2. 准备工作2.1.   为什么要过滤器?
在这里,我们可以将CAN总线看成一个广播消息通道,上面传输着各种类型的消息,好比报纸,有体育新闻,财经新闻,政治新闻,还有军事新闻,每个人都有自己的喜好,不一定对所有新闻都感兴趣,因此,在看报纸的时候,一般人都是只看自己感兴趣的那类新闻,而过滤掉其他不感兴趣的内容。

使用特权

评论回复
沙发
l63t89|  楼主 | 2022-4-30 18:31 | 只看该作者
那么我们一般是怎么过滤掉那些不感兴趣的内容的呢?下面有两种方法来实现这个目的:

第一种方法:

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

使用特权

评论回复
板凳
l63t89|  楼主 | 2022-4-30 18:32 | 只看该作者
第二种方法:

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

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

使用特权

评论回复
地板
l63t89|  楼主 | 2022-4-30 18:32 | 只看该作者
2.2.   两种过滤模式(列表模式与掩码模式)
假设我们是bxCAN这个IP的设计者,现在由我们来设计过滤器,那么我们该如何设计呢?

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

使用特权

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

使用特权

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

使用特权

评论回复
7
l63t89|  楼主 | 2022-4-30 18:35 | 只看该作者
如上图,身份*中第7~10这4位数表示的是出生年份,那么,我们可以这么执行:

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

使用特权

评论回复
8
l63t89|  楼主 | 2022-4-30 18:36 | 只看该作者
再变下,假设现在使用机器来当守卫,不再是人来执行这个“筛选”工作。机器是死的,没有人那么灵活,那么机器又该如何执行呢?

使用特权

评论回复
9
l63t89|  楼主 | 2022-4-30 18:37 | 只看该作者
对于机器来说,每一步都得细化到机器可以理解的程度,于是我们可以作如下细化:

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

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

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

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

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

使用特权

评论回复
10
l63t89|  楼主 | 2022-4-30 18:38 | 只看该作者
2.3.   验证码与屏蔽码
仔细查看上面4个步骤,这不就是C代码中的if语句吗?如下:

使用特权

评论回复
11
l63t89|  楼主 | 2022-4-30 18:39 | 只看该作者
if( x & y ==z) //x表示待检查身份*号码,y表示只关注第7~9位的屏蔽码,Z则为1156,这里叫做验证码
{
        //可以通过
}
else
{
        //不可以通过
}

使用特权

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

使用特权

评论回复
13
l63t89|  楼主 | 2022-4-30 18:40 | 只看该作者
整个判别流程如下所示:

使用特权

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

使用特权

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

使用特权

评论回复
16
l63t89|  楼主 | 2022-4-30 18:42 | 只看该作者
2.4.   列表模式与掩码模式的对比
综合之前所述,下面我们来对比一下列表模式与掩码模式这两种模式的优缺点。

使用特权

评论回复
17
l63t89|  楼主 | 2022-4-30 18:43 | 只看该作者

使用特权

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

使用特权

评论回复
19
l63t89|  楼主 | 2022-4-30 19:41 | 只看该作者

使用特权

评论回复
20
l63t89|  楼主 | 2022-4-30 19:46 | 只看该作者
如上图所示,标准CAN ID存放在上图ID18~ID28中,共11位。随着工业发展,后来发现11位的CAN ID已经不够用,于是就增加了18位,扩展CAN ID到29位,如下图所示:

使用特权

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

本版积分规则

90

主题

798

帖子

1

粉丝