基于stm32f4的can通信-补充

文章讲述了在STM32F4微控制器中调试CAN通信时,从最初使用阻塞比较导致多设备接收丢包,到改用中断接收方法,显著减少丢包现象的过程。通过定义接收结构体和中断函数,实现了对多个CAN设备数据的有效接收和管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前在调试stm32f4-CAN通信中,接收多个ID设备信息时,用到了阻塞比较,而未用到中断接收,这会导致系统中连接多个CAN设备时,程序中CAN接收数据大幅丢包的情况,因此后来更正了CAN中断接收部分程序,现记录如下:

volatile int can_complete=false;//接收完成中断
//结构体
typedef struct
{
	u32 id;
	u32 can_id;//can设备ID
	int update;//数据是否有更新
	u8 len;//数据长度
	u8 data[8];//存储数据
}can_recieve_s;
//接收can设备数量
#define MAX_NUMBER 10

static can_recieve_s can_recieve[MAX_NUMBER]={0};

void CAN_MODE_INIT(//)
{
	//
	CAN底层配置
	//
	//can设备ID匹配
	can_recieve[0].can_id=0x01;
	can_recieve[1].can_id=0x02;
	can_recieve[2].can_id=0x03;
	can_recieve[3].can_id=0x04;
	can_recieve[4].can_id=0x05;
	can_recieve[5].can_id=0x06;
	can_recieve[6].can_id=0x07;
	can_recieve[7].can_id=0x08;
	can_recieve[8].can_id=0x09;
	can_recieve[9].can_id=0x0A;
	//
	for(i=0;i<MAX_NUMBER;i++)
	 {
	  can_recieve[i].update=0;
	 }
	//
	//安装can中断函数
	//
}
//can接收中断函数
void ProcessIRQSrc_CAN1(void)
{
	u8 index=0;
	CanRxMsg RxMessage;
	CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据
    
    for(index=0;index<MAX_NUMBER;index++)
    {
       if(RxMessage.StdId==can_recieve[index].can_id)
       {
          //数据有更新
          can_recieve[index].update=1;
       
          //填充数据
          can_recieve[index].data[0]=RxMessage.Data[0];
          can_recieve[index].data[1]=RxMessage.Data[1];
          can_recieve[index].data[2]=RxMessage.Data[2];
          can_recieve[index].data[3]=RxMessage.Data[3];
          can_recieve[index].data[4]=RxMessage.Data[4];
          can_recieve[index].data[5]=RxMessage.Data[5];
          can_recieve[index].data[6]=RxMessage.Data[6];
          can_recieve[index].data[7]=RxMessage.Data[7];
		  
		  can_recieve[index].len=RxMessage.DLC;
          break;
       }
    }
    can_complete=true;//标记读取完成


}


//can接收读取函数,将接收的数据存储到*buf中,长度为*len,
//id为期望can设备ID。返回状态ret=1;接收失败 ret=0;接收成功
long can_read_id(u8 *buf , u16 *len , u32 id)
{

	u8 datalen=0;
	long ret=0;
	u8 index=0;
	
	//标准数据帧
	CanRxMsg RxMessage;
	RxMessage.IDE=CAN_ID_Standard;
	RxMessage.RTR=CAN_RTR_Data;
	
	//如果数据有更新
	if(can_complete==true)
	{   
	   //遍历数组
	     for(index=0;index<MAX_NUMBER;index++)
	    {
	       if(id==can_recieve[index].can_id)
	       {
	          if( can_recieve[index].update==1)
	          {
	              datalen=can_recieve[index].len;
	             //填充数据,转移数据
		          buf[0]=can_recieve[index].data[0];
		          buf[1]=can_recieve[index].data[1];
		          buf[2]=can_recieve[index].data[2];
		          buf[3]=can_recieve[index].data[3];
		          buf[4]=can_recieve[index].data[4];
		          buf[5]=can_recieve[index].data[5];
		          buf[6]=can_recieve[index].data[6];
		          buf[7]=can_recieve[index].data[7];
	         
		          //数据转移完毕
		          can_recieve[index].update=0;
		          ret=0;
	          }
	          else
	          {
	              //接收失败状态传递
			       datalen=0;
			       ret=1;
	          }
	           break;
	        }
	    }
	    can_complete=faule;//标记清零
	}
    else
    {
        //接收失败状态传递
	    datalen=0;
	    ret=1;
	}
	
   *len=datalen;
   //返回ret
   return ret;

}

应用以上CAN接收函数,在实际系统中,连接多个CAN设备,确实大幅减少了数据的丢包现象。即采用中断接收+读取函数的方式,可以很好地解决多级设备连接的数据接收问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值