STM32F105 CAN通信过滤器配置问题

总结一些最近做项目对CAN通信的过滤器配置的理解;

  1. 这里我使用STM32F105系列的芯片,有2路CAN,我使用的是CAN2,过滤器可以设置从15开始,当然,从1开始也是没有问题的;
  2. 当设置了CAN过滤器,表示只能接收指定ID的数据,其他ID发送过来的数据,不再触发CAN中断,可以进一步提高系统的稳定性。当CAN总线上数据比较多的时候,是很有必要的。
    具体配置如下:
	CAN_SlaveStartBank(15); // can2筛选器组从15开始 
	CAN_FilterInitStructure.CAN_FilterNumber=15; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	//表示只能接收接收方ID为0x11,发送方ID为0x14的数据,具体看通信协议
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1114; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);

如果要设置多个过滤器,继续配置如下:

	CAN_FilterInitStructure.CAN_FilterNumber=16; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1113; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);

以此类推。
3. 单独使用CAN2的时候必须开启先CAN1的时钟,否则收不到数据;
CAN完整的初始化代码(注意F105系列的CAN2时钟使能部分):

//CAN模式初始化
//参数 tsjw :重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//参数 tbs2 :时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
//参数 tbs1 :时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
//参数 brp ;波特率分频器.范围:1~1024;  tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//示例:Fpclk1的时钟在初始化的时候设置为36M,如果设置 CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
//则波特率为:(pclk1/((tsjw+tbs2+tbs1)*brp)) = 36Mhz/18/4 = 500Kbits
//参数 mode :模式设置: mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式; 
//CAN普通模式初始化, 波特率500Kbps 
//返回值:0,初始化OK;
//    其他,初始化失败;
//这里我使用正常模式;CAN_Mode_Init(CAN_SJW_1tq,CAN_BS1_4tq,CAN_BS2_7tq,6,CAN_Mode_Normal);//正常模式
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
	GPIO_InitTypeDef 		GPIO_InitStructure; //声明结构体
	CAN_InitTypeDef        	CAN_InitStructure;
	CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
	
	NVIC_InitTypeDef  		NVIC_InitStructure;//CAN接收RX0中断使能
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PORTB时钟	                   											 

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //新增 注意
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//使能CAN2时钟	 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);			//初始化IO
	
	//CAN单元设置
  CAN_InitStructure.CAN_TTCM = DISABLE;//禁止时间触发通信模式
	CAN_InitStructure.CAN_ABOM = ENABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
//  CAN_InitStructure.CAN_ABOM = DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1后清0后,一旦硬件检测到128次11位连续的隐形位,就退出离线状态(软件自动离线管理)
  CAN_InitStructure.CAN_AWUM = DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)???
  CAN_InitStructure.CAN_NART = DISABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
//	CAN_InitStructure.CAN_NART = ENABLE;//禁止报文自动传送 
  CAN_InitStructure.CAN_RFLM = DISABLE;//报文不锁定,新的覆盖旧的  
	CAN_InitStructure.CAN_TXFP = ENABLE;  /* 发送优先级  0---由标识符决定  1---由发送请求顺序决定	*/
//	CAN_InitStructure.CAN_TXFP = DISABLE;//发生FIFO的优先级由报文的标识符决定
  CAN_InitStructure.CAN_Mode = mode;//模式设置: mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式; 
  
  //设置波特率
  CAN_InitStructure.CAN_SJW = tsjw;//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq  CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
  CAN_InitStructure.CAN_BS1 = tbs1;//Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
  CAN_InitStructure.CAN_BS2 = tbs2;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~	CAN_BS2_8tq
	
	//(pclk1/((1+8+9)*4)) = 36Mhz/18/4 = 500Kbits
	//(pclk1/((1+4+7)*6)) = 36Mhz/18/4 = 500Kbits
  CAN_InitStructure.CAN_Prescaler = brp; 
        
  CAN_Init(CAN2, &CAN_InitStructure);
	
	#if 1
	//待优化
	CAN_SlaveStartBank(15); // can2筛选器组从15开始 
	CAN_FilterInitStructure.CAN_FilterNumber=15; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1114; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);

	CAN_FilterInitStructure.CAN_FilterNumber=16; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1113; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);
	
	CAN_FilterInitStructure.CAN_FilterNumber=17; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1115; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);
	
	CAN_FilterInitStructure.CAN_FilterNumber=18; 
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; 
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x1116; 
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xffff; 
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; 
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
	CAN_FilterInit(&CAN_FilterInitStructure);
	#endif
	
	CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);				//FIFO0消息挂号中断允许.		    

	NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;    //优先级配置,比较特殊 	USB_LP_CAN1_RX0_IRQn
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;     // 主优先级为1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
	NVIC_Init(&NVIC_InitStructure);
	
}

你可能感兴趣的:(STM32)