stm32中的CAN通讯列表模式配置解析与源码

在这里插入图片描述
选择两个32位筛选器,列表模式的话就是14*2=28个CAN帧。
假如我想要筛选一个0x10f46601的帧,它的二进制为:
0001 0000 1111 0100 0110 0110 0000 0001
而筛选器为:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx x100 ,后面的100是因为扩展数据帧
也就是说把上面要筛选的帧弄到这个筛选的X中,即:
1 0000 1111 0100 0110 0110 0000 0001 100 ,整理一下有:
1000 0111 1010 0011 0011 0000 0000 1100 ==0x87a3 300c
整到结构体中就是

CAN_FilterInitStructure.CAN_FilterIdHigh= 0x87a3;		//授时帧0x10f46601//要过滤的ID高位 
    CAN_FilterInitStructure.CAN_FilterIdLow= 0x300c;

观察上面可知:0001 0000 1111 0100 011 // 0 0110 0000 0001
所以CAN_FilterIdHigh=(0x10f46601>>13) & 0xffff
CAN_FilterIdLow= ((0x10f46601<<3) | 0x04) & 0xffff
完整配置如下,筛选3*2=6个帧

static void CAN_Filter_Config()
{
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;

	/*CAN过滤器初始化*/
	  CAN_FilterInitStructure.CAN_FilterNumber=0;						//过滤器组0
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList;	   //工作在列表模式//工作在标识符屏蔽位模式
	  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;	//过滤器位宽为单个32位。
	/* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */

    CAN_FilterInitStructure.CAN_FilterIdHigh= 0x87a3;		//授时帧0x10f46601//要过滤的ID高位 
    CAN_FilterInitStructure.CAN_FilterIdLow= 0x300c;	 
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (((0x10f46602)>>13)&0xffff);    //授时帧0x10f46602
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= (((((uint32_t)0x10f46602)<<3)|(0x00000004))&0xffff);
	  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;							//过滤器被关联到FIFO0
	  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;										//使能过滤器
	  CAN_FilterInit(&CAN_FilterInitStructure);
	
	  CAN_FilterInitStructure.CAN_FilterNumber=1;						//过滤器组1
	  CAN_FilterInitStructure.CAN_FilterIdHigh=((((0x08840001|(Derailment_Addr<<8) ))>>13)&0xffff);     //收到主机1给予的控制帧
	  CAN_FilterInitStructure.CAN_FilterIdLow=(((((uint32_t)(0x08840001|(Derailment_Addr<<8) ))<<3)|(0x00000004))&0xffff);
	  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=((((0x08840002|(Derailment_Addr<<8) ))>>13)&0xffff);     //收到主机2给予的控制帧
	  CAN_FilterInitStructure.CAN_FilterMaskIdLow=(((((uint32_t)(0x08840002|(Derailment_Addr<<8) ))<<3)|(0x00000004))&0xffff);
	  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;							//过滤器被关联到FIFO0
	  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;										//使能过滤器
	  CAN_FilterInit(&CAN_FilterInitStructure);
	
	  CAN_FilterInitStructure.CAN_FilterNumber=2;						//过滤器组2
	  CAN_FilterInitStructure.CAN_FilterIdHigh= (((( 0x04780001|(Derailment_Addr<<8) ))>>13)&0xffff);     //收到主机1关于报警帧的响应
	  CAN_FilterInitStructure.CAN_FilterIdLow= (((((uint32_t)( 0x04780001|(Derailment_Addr<<8) ))<<3)|(0x00000004))&0xffff);
	  CAN_FilterInitStructure.CAN_FilterMaskIdHigh= (((( 0x04780002|(Derailment_Addr<<8) ))>>13)&0xffff);    //收到主机2关于报警帧的响应
    CAN_FilterInitStructure.CAN_FilterMaskIdLow= (((((uint32_t)( 0x04780002|(Derailment_Addr<<8) ))<<3)|(0x00000004))&0xffff);
	  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;							//过滤器被关联到FIFO0
	  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;										//使能过滤器
	  CAN_FilterInit(&CAN_FilterInitStructure);
	
  	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);     /*CAN通信中断使能*/
}

猜你喜欢

转载自blog.csdn.net/qq_40831436/article/details/98763264