纪要

CAN(Controller Area Network)总线是一种广泛应用于工业控制和汽车电子领域的串行通信协议。在CAN总线中,节点间通过CAN总线发送和接收消息。每个CAN帧包含一个标准或扩展标识符(ID)和数据负载。

CAN总线帧过滤器是一个硬件组件,可用于过滤传输到节点的CAN帧。帧过滤器允许节点只处理其所需的CAN帧,从而降低总线负载和系统处理开销。帧过滤器可以配置为基于标准或扩展ID进行过滤,也可以使用ID掩码匹配特定的CAN帧。

实际应用中基本都用扩展帧,因为标准帧的11bit id实在是太捉急了,放不了什么内容
在配置了CAN过滤器后,发现指定的一些帧收不到但是总线上收到了这些帧

问题描述

目前所采用的为CAN的扩展帧模式,需要过滤出类似0x04FB2028这种xxFBxxxx的报文,但是发现一个问题FB16的报文被接收到了,但是FB20这种报文被滤除了,这时候我就怀疑了是Filter配置错误

CAN_FilterInitStructure.Filter_Num= CAN_FILTERNUM5;CAN_FilterInitStructure.Filter_Mode = CAN_Filter_IdMaskMode;CAN_FilterInitStructure.Filter_Scale= CAN_Filter_32bitScale;CAN_FilterInitStructure.Filter_HighId = CAN_FILTER_EXTID_H(0x04FB2028);CAN_FilterInitStructure.Filter_LowId= CAN_FILTER_EXTID_L(0x04FB2028);CAN_FilterInitStructure.FilterMask_HighId = 0x00FF;CAN_FilterInitStructure.FilterMask_LowId= 0x0000;CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;CAN_FilterInitStructure.Filter_Act= ENABLE;CAN1_InitFilter(&CAN_FilterInitStructure);

#define CAN_FILTER_EXTID_H(EXTID) ((uint16_t)(((EXTID) >> 13) & 0xFFFF))#define CAN_FILTER_EXTID_L(EXTID) ((uint16_t)(((uint32_t)(EXTID) << 3U) | ((uint8_t)CAN_ID_EXT)))

问题解决

首先我们来看下扩展帧的报文格式

CAN扩展帧ID范围为0x000000000x1FFFFFFF是因为最后3位是 IDE RTR 0其实可用部分只有29bit
配置过滤器也是如此,下面是过滤器的寄存器内容
配置过滤器有两种模式精准过滤(filter list mode)规则过滤(Mask mode),根据上面所述我们需要的是 Mask mode。
看上表中filter idfilter mask每一位都是对齐的,并且开始的 3bits 对我们而言是无意义的,所以我们上面对filter id配置了偏移,下面对应的对于filter mask 也需要做相同的操作。

CAN_FilterInitStructure.Filter_Num= CAN_FILTERNUM3;CAN_FilterInitStructure.Filter_Mode = CAN_Filter_IdMaskMode;CAN_FilterInitStructure.Filter_Scale= CAN_Filter_32bitScale;CAN_FilterInitStructure.Filter_HighId = CAN_FILTER_EXTID_H(0x04FB2028);CAN_FilterInitStructure.Filter_LowId= CAN_FILTER_EXTID_L(0x04FB2028);CAN_FilterInitStructure.FilterMask_HighId = CAN_FILTER_EXTID_H(0x00FF0000);CAN_FilterInitStructure.FilterMask_LowId= CAN_FILTER_EXTID_L(0x00FF0000);CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;CAN_FilterInitStructure.Filter_Act= ENABLE;CAN1_InitFilter(&CAN_FilterInitStructure);

如此配置后CAN可以正确过滤出 xxFBxxxx的报文了。