CAN过滤器
1、配置过滤器必须使过滤器组工作在初始化模式,配置完成后进入正常模式
CAN1->FMR|=1<<0; //过滤器组0工作在初始化模式
//CAN1->FMR|=1<<n; //过滤器组n工作在初始化模式
/*...配置*/
CAN1->FMR&=0<<0; //过滤器组0进入正常模式
//CAN1->FMR&=0<<n; //过滤器组n进入正常模式
2、配置某个过滤器时也要先关闭该过滤器的激活
CAN1->FA1R&=~(1<<0); //过滤器0不激活
//CAN1->FA1R&=~(1<<n); //过滤器n不激活
CAN1->FA1R|=1<<0; //激活过滤器0
//CAN1->FA1R|=1<<n; //激活过滤器n
3、设置过滤器位宽,有32位和16位两种模式,这个影响到后面过滤屏蔽的ID长度
CAN1->FS1R|=1<<0; //过滤器0位宽为32位
CAN1->FS1R&=~(1<<0); //过滤器0位宽为16位
CAN1->FS1R|=1<<n; //过滤器n位宽为32位
CAN1->FS1R&=~(1<<n); //过滤器n位宽为16位
STID标准ID
EXID扩展ID
IDE
RTR
32位模式
CAN_FxR1[31:21] | CAN_FxR1[20:3] | CAN_FxR1[2] | CAN_FxR1[1] | CAN_FxR1[0] |
---|---|---|---|---|
CAN_FxR2[31:21] | CAN_FxR2[20:3] | CAN_FxR2[2] | CAN_FxR2[1] | CAN_FxR2[0] |
STID[10:0] | EXID[17:0] | IDE | RTR | 0 |
16位模式
CAN_FxR1[15:5] | CAN_FxR1[4] | CAN_FxR1[3] | CAN_FxR1[2:0] |
---|---|---|---|
CAN_FxR1[31:21] | CAN_FxR1[20] | CAN_FxR1[19] | CAN_FxR1[18:16] |
CAN_FxR2[15:5] | CAN_FxR2[4] | CAN_FxR2[3] | CAN_FxR2[2:0] |
CAN_FxR2[31:21] | CAN_FxR2[20] | CAN_FxR2[19] | CAN_FxR2[18:16] |
STID[10:0] | IDE | RTR | EXID[17:15] |
4、设置过滤器工作模式,标识符屏蔽位模式和标识符列表模式
CAN1->FM1R&=~(1<<0); //过滤器0工作在标识符屏蔽位模式
CAN1->FM1R|=1<<0; //过滤器0工作在标识符列表模式
CAN1->FM1R&=~(1<<n); //过滤器n工作在标识符屏蔽位模式
CAN1->FM1R|=1<<n; //过滤器n工作在标识符列表模式
5、过滤器关联到FIFOn n=0,1
CAN1->FFA1R&=~(1<<0); //过滤器0关联到FIFO0
CAN1->FFA1R|=1<<0; //过滤器0关联到FIFO1
CAN1->FFA1R&=~(1<<n); //过滤器n关联到FIFO0
CAN1->FFA1R|=1<<n; //过滤器n关联到FIFO1
6、设置过滤规则
CAN1->sFilterRegister[0].FR1=0x21<<21;//32位ID
CAN1->sFilterRegister[0].FR2=(0x7F<<21);//32位MASK
标识符模式
寄存器的每位对应于所期望的标识符的相应位的电平。
0: 期望相应位为显性位;
1: 期望相应位为隐性位。
屏蔽位模式
寄存器的每位指示是否对应的标识符寄存器位一定要与期望的标识符的相应位一致。
0: 不关心,该位不用于比较;
1: 必须匹配,到来的标识符位必须与滤波器对应的标识符寄存器位相一致
标识符模式就是FR2为1的位标识出需要验证的位,FR1说明被标识出的位必须是什么,也就是一个过滤器一个规则,此处的逻辑类似于&运算
CAN1->sFilterRegister[0].FR1=0x21<<21;//32位ID
CAN1->sFilterRegister[0].FR2=(0x7F<<21);//32位MASK
//表示检查SDID标准帧ID的低七位,低七位必须是0x21的才能通过
屏蔽位模式 则是规定特定的一个ID,ID的所有位都要符合设置值
CAN1->sFilterRegister[0].FR1=0x21<<21;//32位ID
CAN1->sFilterRegister[0].FR2=0xFF<<21)//32位MASK
//只有0x00和0xFF可以通过过滤
程序例程
void CAN_Set_Filter(u8 Addr)
{
Addr=Addr&0x7F;
//过滤器初始化
CAN1->FMR|=1<<0; //过滤器组工作在初始化模式
/*过滤规则1 CAN ID的低七位必须与Addr一致,其他位不关心 */
CAN1->FA1R&=~(1<<0); //过滤器0不激活
CAN1->FS1R|=1<<0; //过滤器位宽为32位.
CAN1->FM1R|=0<<0; //过滤器0工作在标识符屏蔽位模式
//CAN1->FM1R|=1<<0; //过滤器0工作在标识符列表模式
CAN1->FFA1R|=0<<0; //过滤器0关联到FIFO0
CAN1->sFilterRegister[0].FR1=Addr<<21;//32位ID
CAN1->sFilterRegister[0].FR2=(0x7F<<21);//32位MASK
CAN1->FA1R|=1<<0; //激活过滤器0
/*过滤规则2 CAN ID的第7位必须为1,即只有0x80可以通过*/
CAN1->FA1R&=~(1<<1); //过滤器1不激活
CAN1->FS1R|=1<<1; //过滤器1位宽为32位.
//AN1->FM1R|=0<<1; //过滤器1工作在标识符屏蔽位模式
CAN1->FM1R|=1<<1; //过滤器1工作在标识符列表模式
CAN1->FFA1R|=0<<1; //过滤器1关联到FIFO0
CAN1->sFilterRegister[1].FR1=0x80<<21;//32位ID
CAN1->sFilterRegister[1].FR2=(0x80<<21);//32位MASK
CAN1->FA1R|=1<<1; //激活过滤器1
/*过滤规则3 CAN ID的低八位必须为0x00*/
CAN1->FA1R&=~(1<<2); //过滤器2不激活
CAN1->FS1R|=1<<2; //过滤器2位宽为32位.
CAN1->FM1R|=0<<2; //过滤器2工作在标识符屏蔽位模式
//CAN1->FM1R|=1<<2; //过滤器2工作在标识符列表模式
CAN1->FFA1R|=0<<2; //过滤器2关联到FIFO0
CAN1->sFilterRegister[2].FR1=0x00<<21;//32位ID
CAN1->sFilterRegister[2].FR2=(0xFF<<21);//32位MASK
CAN1->FA1R|=1<<2; //激活过滤器2
CAN1->FMR&=0<<0; //过滤器组进入正常模式
}