解决STM32F407的CAN2无法进入接收中断的方法

1.要先使能CAN1的时钟,再使能CAN2的时钟

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//使能CAN2时钟

2.过滤器配置在14-27之间

	CAN_FilterInitStructure.CAN_FilterNumber=15;//过滤器15
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//32位
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
	CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化

这个问题困扰了我两天,今天偶然看到一篇文章有讲这个:STM32 CAN1 CAN2 不能同时工作,最后原因竟然是。。。。

看了之后恍然大悟。下面贴上我的初始化代码:

主函数进行中断优先级分组和CAN初始化调用及使能

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组
CAN2_Mode_Init(CAN_SJW_1tq, CAN_BS1_7tq, CAN_BS2_6tq, 12, CAN_Mode_Normal);//配置并启动CAN接口  250k波特率

初始化代码:

//CAN2初始化
void CAN2_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
{
	GPIO_InitTypeDef		GPIO_InitStructure; 
	CAN_InitTypeDef			CAN_InitStructure;
	CAN_FilterInitTypeDef	CAN_FilterInitStructure;
		
	NVIC_InitTypeDef		NVIC_InitStructure;
	
	CAN_DeInit(CAN2);
	CAN_StructInit(&CAN_InitStructure);
	
	//使能相关时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能PORTB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//使能CAN2时钟
	
	//初始化GPIO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB12,PB13
	
	//引脚复用映射配置
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_CAN2); //GPIOB12复用为CAN2
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_CAN2); //GPIOB13复用为CAN2
	
	//CAN单元设置
	CAN_InitStructure.CAN_TTCM=DISABLE;	//非时间触发通信模式
	CAN_InitStructure.CAN_ABOM=DISABLE;	//启用软件自动离线管理 ENABLE
	CAN_InitStructure.CAN_AWUM=DISABLE;	//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
	CAN_InitStructure.CAN_NART=ENABLE;	//禁止报文自动传送
	CAN_InitStructure.CAN_RFLM=DISABLE;	//报文不锁定,新的覆盖旧的
	CAN_InitStructure.CAN_TXFP=DISABLE;	//优先级由报文标识符决定
	
	CAN_InitStructure.CAN_Mode= mode;//模式设置
	CAN_InitStructure.CAN_SJW=tsjw;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
	CAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
	CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
	CAN_InitStructure.CAN_Prescaler=brp;  //分频系数(Fdiv)为brp+1
	
	CAN_Init(CAN2, &CAN_InitStructure);// 初始化CAN2
	
		//配置过滤器
	CAN_FilterInitStructure.CAN_FilterNumber=15;//过滤器15
	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//32位
	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
	CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
	
#if CAN2_RX0_INT_ENABLE
	
	CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);//FIFO0消息挂起中断允许   
	
	
	NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 主优先级为3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;// 次优先级为3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&NVIC_InitStructure);
#endif
}

中断服务函数:

//CAN2_RX0中断服务函数
void CAN2_RX0_IRQHandler(void)
{
	printf("中断发生\r\n");
	
	CAN_Receive(CAN2, CAN_FIFO0, &CAN2RxMessage);//将CANFIFO中收到的数据储存到“CAN2RxMessage”变量中
	
	CAN2_rx_flag = FLAG_OK;//标志位置位
	
	printf("can2irq\r\n");
}

效果展示:

 CAN逻辑分析仪数据:

 

物联沃分享整理
物联沃-IOTWORD物联网 » 解决STM32F407的CAN2无法进入接收中断的方法

发表评论