STM32F4 CAN1 CAN2中断接收数据

CAN1总线发送,中断接收。
平台:STM32F405RGT6、标准库。

CAN1配置

void CAN1_Mode_Init(u8 mode)
{
  	GPIO_InitTypeDef GPIO_InitStructure; 
	CAN_InitTypeDef        CAN_InitStructure;
  	CAN_FilterInitTypeDef  CAN_FilterInitStructure;
   	NVIC_InitTypeDef  NVIC_InitStructure;

    //使能相关时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟	                   											 
  	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟	
	
    //初始化GPIO
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
    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(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
	
	//引脚复用映射配置
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
	  
  	//CAN单元设置
   	CAN_InitStructure.CAN_TTCM=DISABLE;	//非时间触发通信模式   
  	CAN_InitStructure.CAN_ABOM=DISABLE;	//软件自动离线管理	  
  	CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
  	CAN_InitStructure.CAN_NART=ENABLE;	//禁止报文自动传送 
  	CAN_InitStructure.CAN_RFLM=DISABLE;	//报文不锁定,新的覆盖旧的  
  	CAN_InitStructure.CAN_TXFP=DISABLE;	//优先级由报文标识符决?
	 
/***************************************************************************************/		
    //配置can工作模式	
  	CAN_InitStructure.CAN_Mode= mode;	 //模式设置 
		//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);
		//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
		//Fpclk1的时钟在初始化的时候设置为42M,如果设置CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack);
		//则波特率为:42M/((6+7+1)*6)=500Kbps
		//返回值:0,初始化OK;
		//    其他,初始化失败; 
		/* // 100K
  	CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //时间段1的时间单元.  Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_6tq; //时间段2的时间单元.  Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=6;  //分频系数(Fdiv)为brp+1	
		*/
		
		/* // 50K
  	CAN_InitStructure.CAN_SJW=CAN_SJW_3tq;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //时间段1的时间单元.  Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //时间段2的时间单元.  Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=84;  //分频系数(Fdiv)为brp+1	
		*/
		
		 // 25K
  	CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //时间段1的时间单元.  Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //时间段2的时间单元.  Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=210;  //分频系数(Fdiv)为brp+1	
				
		
		 /*// 20K
  	CAN_InitStructure.CAN_SJW=CAN_SJW_3tq;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //时间段1的时间单元.  Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //时间段2的时间单元.  Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=210;  //分频系数(Fdiv)为brp+1	
		*/
		
		/* // 10K
  	CAN_InitStructure.CAN_SJW=CAN_SJW_3tq;	//重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=CAN_BS1_6tq; //时间段1的时间单元.  Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //时间段2的时间单元.  Tbs2范围CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=420;  //分频系数(Fdiv)为brp+1	
		*/
		
/***************************************************************************************/			
  	CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1 
    
		//配置过滤器
 	CAN_FilterInitStructure.CAN_FilterNumber=0;	  //过滤器0
  	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);//滤波器初始化
		
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许.		    
  
  	NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
}   

CAN1发送函数

u8 CAN1_Send_Msg(u8* msg,u8 len)
{	
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;	 // 标准标识符为0
  TxMessage.ExtId=0x12;	 // 设置扩展标示符(29位)
  TxMessage.IDE=0;		   // 使用扩展标识符
  TxMessage.RTR=0;		   // 消息类型为数据帧,一帧8位
  TxMessage.DLC=len;	   // 发送两帧信息
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];				 // 第一帧信息          
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//等待发送结束
  if(i>=0XFFF)return 1;
  return 0;		
}

CAN1中断服务函数

void CAN1_RX0_IRQHandler(void)
{
	CanRxMsg RxMessage;
	//CAN_Receive(CAN1, 0, &RxMessage);
	CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据	
	led_cnt=0;
	falshCnt=0;
	ledSpeed=FLASH_FAST;
}

代码运行现象:数据3秒发一次,CAN1中断函数收到数据之后LED快闪3次,然后又恢复到1秒1闪。
下面是工程文件,里面还包括CAN2的中断接收函数。
STM32F4 CAN1 CAN2数据收发 中断接收

### 回答1: STM32 HAL CAN中断接收,是指在使用STM32芯片和HAL库编程时,通过CAN总线的中断方式来接收数据。CAN总线是一种常用于工控和汽车电子领域的通讯总线,采用异步传输方式,具有高速、可靠和抗干扰性强等特点。 在使用HAL库编程时,可以通过配置CAN总线的中断处理函数来实现CAN总线的中断接收功能。具体操作包括以下步骤: 1. 初始化CAN总线和相关的GPIO引脚,并配置CAN总线的CAN接收中断使能。 2. 定义CAN的中断处理函数,在CAN数据接收时自动调用。在函数中可以实现接收的数据处理、状态更新、回应等操作。 3. 在主程序中启用CAN的中断,以便可以在数据到达时及时响应。 4. 在CAN中断处理函数中实现数据的解析和处理,并保存到相应的数据缓冲区或变量中,以便供上层应用程序调用。 需要注意的是,CAN总线的中断接收功能需要与发送功能配合使用,才能实现双向数据传输。例如,在接收到数据后需要进行数据处理、状态更新,并向发送方回复响应,以保证数据的可靠传输和通信的完整性。 总之,STM32 HAL CAN中断接收是一种基于中断处理函数的数据接收方式,它可以实现数据的可靠传输和快速响应,广泛应用于工控和汽车电子等领域。 ### 回答2: STM32 HAL CAN 是一种基于HAL库的CAN总线通信协议。其中断接收是指当CAN的接收FIFO缓冲区中有新的数据传入时,通过配置CAN的中断来触发中断服务程序的执行,并将接收到的数据存储在相应的缓冲区中。 使用STM32 HAL CAN进行中断接收的步骤如下: 1.初始化CAN:使用HAL_CAN_Init函数初始化CAN总线,并设置通信速率、帧格式、过滤器、中断等参数。 2.使能CAN中断:使用HAL_CAN_ActivateNotification函数使能CAN中断。如果要使能RS232的中断,还需使用HAL_CAN_ConfigInterrupt函数来配置RS232的中断模式。 3.在中断服务程序中实现数据接收:配置CAN的中断服务程序,并在程序中使用HAL_CAN_Receive_IT函数实现CAN数据的接收和存储。在此过程中,还需使用HAL_CAN_GetRxMessage函数来获取接收到的数据,并将其存储在相应的缓冲区中。 需要注意的是,在中断接收过程中,还需注意CAN总线的数据处理速度。如果数据处理速度太慢,会导致FIFO缓冲区溢出,从而无法存储全部的数据。因此,建议使用DMA的方式来实现数据的处理和存储,以提高CAN总线的数据处理效率。 总之,STM32 HAL CAN 中断接收是一种基于中断方式实现的CAN总线通信协议,通过配置CAN的中断,实现对接收数据的读取和存储。在实际应用中,需要结合具体的场景和要求来选取合适的CAN通信协议和实现方式。 ### 回答3: STM32 HAL是ST公司为了方便STM32系列单片机开发者开发应用程序而推出的一套开发库。CAN是一种串行通信总线,用于连接微控制器和外部设备。在STM32 HAL中实现CAN中断接收的方法如下: 1. 配置CAN模块:在使用CAN模块前首先对CAN模块进行配置,包括波特率、模式等配置。 2. 开启CAN中断:使用HAL_CAN_ActivateNotification函数开启CAN的中断,设置回调函数。 3. 编写CAN接收回调函数:在CAN中断发生时,将调用CAN接收回调函数。在CAN接收回调函数中,可以获取接收到的CAN数据并进行处理,如解析数据、发送响应等操作。 4. 启动CAN模块:配置完成后,使用HAL_CAN_Start函数启动CAN模块,开始接收CAN数据。 5. 等待并处理CAN数据:CAN数据接收后,在CAN接收回调函数中进行处理。如果没有接收到CAN数据,则程序会一直等待,直到CAN数据到达。 通过以上步骤,即可使用STM32 HAL实现CAN中断接收。在CAN通讯系统中,中断接收方式的优点在于响应速度快、实时性高,可以更加有效地处理CAN发来的数据。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗暗星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值