
STM32CAN滤波器、滤波屏蔽器设置详解.docx
15页STM32 CAN过滤器、滤波屏蔽器配置总结下面容为:一、在STM32互联型产品中,CAN1和CAN2分享28个过滤器组,其它 STM32F103xx系列产品中有14个过滤器组,用以对接收到的帧进行过滤1、过滤器组每组过滤器包括了 2个可配置的32位寄存器:CAN_FxR0和CAN_FxR1这些 过滤器相当于关卡,每当收到一条报文时,CAN要先将收到的报文从这些过滤器 上"过"一下,能通过的报文是有效报文,收进相关联FIFO (FIFO1或FIF02), 不能通过的是无效报文(不是发给"我"的报文),直接丢弃标准CAN的标志位长度是11位扩展格式CAN的标志位长度是29 ° CAN2.0A协议规定CAN控制器必须有一个11位的标识符CAN2.0B协议中规定 CAN控制器的标示符长度可以是11位或29位°TM32同时支持CAN2.0A/CAN2.0B 协议°)一IgrJ{畐•过遽器1个32隹过滤歸一标识符辭蔽 :爸号■CAH冷刖|脚阖GAN F^lHSiajtAN Fxfl2 £3.1:24]乍朋爼昶:1剧5TIID(1 0:3]5JI 创生洞 EXID|S7:ia|IGJWI 心]2冲3却芷过弦監一抓淑齣列&龙冲忖閒I ™CaM 金Am田 Dp:D|ID ―CAN.FxR:i[5i^]―|
标识符屏蔽位模式:可过滤出一组标识符此时,这样CAN_FxR0中保存的就是标识符匹配值,CAN_FxRl中保存的是屏蔽码,即CAN_FxR1中如果某一位为1,则CAN_FxR0中相 应的位必须与收到的帧的标志符中的相应位吻合才能通过过滤器;CAN_FxR1中 为0的位表示CAN_FxR0中的相应位可不必与收到的帧进行匹配标识符列表模式:可过滤出一个标识此时CAN_FxR0和CAN_FxR1中的都是要匹配的标识符,收到的帧的标识符必须与其中的一个吻合才能通过过滤注意:CAN_FilterldHigh是指高16位CAN_FilterldLow是低16位应该将需要得到的帧的和过滤器的设置值左对齐起所有的过滤器是并联的,即一个报文只要通过了一个过滤器,就是算是有效 的按工作模式和宽度,一个过滤器组可以变成以下几中形式之一:(1) 1个32位的屏蔽位模式的过滤器2) 2个32位的列表模式的过滤器3) 2个16位的屏蔽位模式的过滤器4) 4个16位的列表模式的过滤器每组过滤器组有两个32位的寄存器用于存储过滤用的"标准值",分别是FxR1 , FxR2 在32位的屏蔽位模式下: 有1个过滤器FxR1用于指定这些位的标准值,FxR2用于指定需要关心哪些位。
在32位的列表模式下: 有2个过滤器FxR1指定过滤器0的标准值,FxR2指定过滤器1的标准值在16位的屏蔽位模式下: 有2个过滤器FxR1配置过滤器0,其中,[31-16]位指定要关心的位,[15-0]位指定 这些位的标准值FxR2配置过滤器1,其中,[31-16]位指定要关心的位,[15-0]位指定 这些位的标准值在16位的列表模式下: 有4个过滤器FxR1的[15-0]位配置过滤器0,FxR1的[31-16]位配置过滤器1FxR2的[15-0]位配置过滤器2,FxR2的[31-16]位配置过滤器3STM32的CAN有两个FIFO,分别是FIFO0和FIFO1为了便于区分 下面FIFO0 写作 FIFO_0,FIFO1 写作 FIFO」每组过滤器组必须关联且只能关联一个FIFO复位默认都关联到FIFO_0所谓“关联”是指假如收到的报文从某个过滤器通过了,那么该报文会被存 到该过滤器相连的FIFO从另一方面来说,每个FIFO都关联了一串的过滤器组,两个FIFO刚好瓜分 了所有的过滤器组每当收到一个报文,CAN就将这个报文先与FIFO_0关联的过滤器比较,如 果被匹配,就将此报文放入FIFO_0中。
如果不匹配,再将报文与FIFO_1关联的过滤器比较,如果被匹配,该报文 就放入F IFO_1中如果还是不匹配,此报文就被丢弃每个FIFO的所有过滤器都是并联的,只要通过了其中任何一个过滤器,该报 文就有效如果一个报文既符合FIFO_0的规定,又符合FIFO_1的规定,显然,根据操 作顺序,它只会放到FIFO_0中每个FIFO中只有激活了的过滤器才起作用,换句话说,如果一个FIFO有20个过滤器,但是只激话了 5个,那么比较报文时,只拿这5个过滤器作比较一般要用到某个过滤器时,在初始化阶段就直接将它激活需要注意的是,每个FIFO必须至少激活一个过滤器,它才有可能收到报文 如果一个过滤器都没有激活,那么是所有报文都报废的一般的,如果不想用复杂的过滤功能,FIF0可以只激活一组过滤器组,且 将它设置成32位的屏蔽位模式,两个标准值寄存器(FxRl,FxR2)都设置成0 这样所有报文均能通过2、过滤器编号过滤器编号用于加速CPU对收到报文的处理收到一个有效报文时,CAN会将收到的报文 以及它所通过的过滤器编 号,一起存入接收中CPU在处理时,可以根据过滤器编号,快速的知道该报 文的用途,从而作出相应处理。
不用过滤器编号其实也是可以的,这时候CPU就要分析所收报文的标识 符,从而知道报文的用途由于标识符所含的信息较多,处理起来就慢一点了 会消耗CPU资源STM32使用以下规则对过滤器编号:(1) FIFO_0和FIFO」的过滤器分别独立编号,均从0开始按顺序编号2) 所有关联同一个FIFO的过滤器,不管有没有被激活,均统一进行编号3) 编号从0开始,按过滤器组的编号从小到大,按顺序排列4) 在同一过滤器组,按寄存器从小到大编号FxR1配置的过滤器编号小,FxR2配置的过滤器编号大5) 同一个寄存器,按位序从小到大编号[15-0]位配置的过滤器编号小, [31-16]位配置的过滤器编号大6) 过滤器编号是弹性的当更改了设置时,每个过滤器的编号都会改变但是在设置不变的情况下,各个过滤器的编号是相对稳定的这样,每个过滤器在自己在FIFO中都有编号在FIFO_0中,编号从0 — (M-1),其中M为它的过滤器总数在FIFO_1中,编号从0 -- (N-1),,其中N为它的过滤器总数一个FIFO如果有很多的过滤器,,可能会有一条报文,在几个过滤器上均 能通过,这时候,,这条报文算是从哪儿过来的呢? STM32在使用过滤器时,按 以下顺序进行过滤:(1) 位宽为32位的过滤器,优先级高于位宽为16位的过滤器。
2) 对于位宽相同的过滤器,标识符列表模式的优先级高于屏蔽位模式3) 位宽和模式都相同的过滤器,优先级由过滤器号决定,过滤器号小的优 先级高按这样的顺序,报文能通过的第一个过滤器,就是该报文的过滤器编号,被存入接收中二、代码:/* CAN1配置函数*/void CAN_Configuration(void){CAN_InitTypeDef CAN_InitStrueture;CAN_FilterlnitTypeDef CAN_FilterlnitStrueture;// CAN register initCAN_DeIni t(CANl);CAN_StruetInit(&CAN_InitStrueture);// CAN cell initCAN_Ini tSt rue ture.CAN_TTCM二DISABLE;//禁止时间触发通信模式CAN_InitStrueture.CAN_ABOM二DISABLE;CAN_InitStrueture.CAN_AWUM二DISABLE;//睡眠模式通过清除 sleep 位 来唤醒CAN_Ini tSt rue ture.CAN_NART二ENABLE;//ENABLE;报文自动重传CAN_InitStrueture.CAN_RFLM二DISABLE;//接收溢出时,FIFO 未锁定CAN_Ini tSt rue ture.CAN_TXFP=DISABLE;//发送的优先级由标示符的大 小决定//设置ean通讯波特率为50KbpsCAN_Ini tStrueture.CAN_BSl=CAN_BSl_8 tq;CAN_InitStrueture.CAN_BS2=CAN_BS2_7tq;CAN_InitStrueture.CAN_Prescaler=45;CAN_Init(CAN1,&CAN_InitStrueture);// CAN filter initCAN_Fil terlni tStrueture.CAN_Fil terNumber=0; //使用 0 号过滤器组CAN_Fil terlni tSt rue ture.CAN_Fil terMode=CAN_Fil terMode_IdMask;//屏蔽位 标识符模式CAN_FilterlnitStrueture.CAN_FilterScale=CAN_FilterScale_32bit;// 1 个32bit的过滤器CAN_Filterlni tStrueture.CAN_FilterldHigh(((u32)slave_id<<21)&0xffff0000)>>16;完全匹配CAN_Filterlni tStrueture.CAN_FilterMaskldLow = OxFFFF; //完全匹配CAN_Filterlni tStrueture.CAN_FilterFIFOAssignment=CAN_FIFO0;//使用 FIFO0CAN_Fil terlni tSt rue ture.CAN_Fil terAc tivat ion=ENABLE; //使能 过滤器CAN_Filterlnit(&CAN_FilterlnitStrueture);CAN_ITConfig(CANl,CAN_IT_FMP0|CAN_IT_EPV, ENABLE);}/*CAN发送函数*/unsigned ehar CAN1_SendData(void){。












