一、关于问题的阐述:最近在完善vesc的CAN通信相关代码,在配置过滤器时碰到了问题。
1.1 对过滤器的两种模式理解不全面
1.1.1 关于过滤器的掩码模式。当时由于学习较浅,始终没有认真学习,主要是不太清楚两个32位的标识符寄存器(CAN_FxR1和CAN_FxR2)中每个位置究竟存放着什么。比如我的11位的标准ID在32位寄存器中的存放位置?现在终于得到解决。
1.1.2 关于过滤器的列表模式。这个的问题主要是出在手上现有的一套祖传代码。这里有一个很迷惑的左移5位的位操作,导致我一直对列表模式不解,现在也得到解决。
1.2 关于vesc中使用的扩展ID在过滤器中配置。
二、解决问题前的知识学习
2.1 CAN的过滤器组
2.1.1 stm32中,CAN共有14个过滤器组,28个32位过滤过滤器,输入值对应为0~27(若同时使用CAN1和CAN2,一般CAN1为0-13,CAN2为14-27),其中每个过滤器组的结构如下。每个过滤器组包含2个32位的寄存器,分别为CAN_FxR0和CAN_FxR1(x=0,1,2....13),它们用来存储要筛选的ID或者掩码。下文中引用的图中FSCx=1代表寄存器的长度(位宽)为32位,FSCx=0代表寄存器的长度为16位。FBMx用来标识过滤器是列表还是掩码模式。
注:当前图中结构是位宽为32位。
2.1.2 对上图的详细解读:在掩码模式下:
(1)过滤器第0位保留空白。
(2)从第3位开始为扩展ID的第0位,EXTID共18位,STID共11位。
(3)过滤器高16位中后5位为扩展ID 。
2.2 CAN屏蔽两种模式
2.2.1 列表模式:
(1)当过滤器的位宽为16时:上图中的两个32位寄存器全部用来存放需要过滤的ID(此时上图中的“映像”标识无用)。一个过滤器组共能存放4个,分别为CAN_FxR1和CAN_FxR1的高16位和低16位。只要收到的ID与过滤器组中的某一个ID匹配即可。(只能过滤标准帧)
(2)当过滤器的位宽为32时:一个过滤器组共能存放2个ID。
(3)位宽:即配置的寄存器的位数:
2.2.2 掩码模式:
(1)当过滤器位宽为32时:一个32位寄存器CAN_FxR0存放要过滤的ID(位置要与上图中的“映像”标识相匹配),另一个32位寄存器CAN_FxR1中的0和1表示接收到的报文是否要与CAN_FxR0中对应位置匹配,0为不要求匹配,1为要求匹配。
(2)当过滤器位宽为16时:也是只能过滤标准帧,但遵循格式见下图。
三、问题的解决
3.1 关于掩码模式中存放要过滤的ID。(这里只谈寄存器位宽为32位下的情况)
3.1.1 若我们要存放的是扩展ID:
解释:id<<3是因为我们的过滤器位置要匹配(见2.1.1中图,前三位分别为0、RTR、IDE),所以在此左移3位。位操作就不用详说了。
3.1.2 若我们要存放的是标准ID:
解释:std_id<<5是因为 2.1.1中图,寄存器高16位中,后5位为扩展ID,所以要左移5位。(可见2.1.2中(3)的说明)
3.1.3 关于对应掩码寄存器中的配置:
3.2 关于列表模式中存放要过滤的ID。(这里只谈寄存器位宽为16位下的情况)
由2.2.2中的表格可知,我们要把标准ID左移5位放入才可。见下图