我是靠谱客的博主 潇洒自行车,最近开发中收集的这篇文章主要介绍ANO匿名飞控STM32代码解读(二)数据传输——Ano_DT.c,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我使用代码对应的上位机版本为v6,具体通信协议格式在打开V6版本上位机–帮助信息–通信协议里可以看到。
这部分数据传输的核心简单的解帧。这部分的讲解以及匿名的通信协议的简介可以看另一篇文章**《串口通信协议》**

核心内容在下面一点,如果只需要研究通信协议可以直接看下面。

先来分析代码

依然注意到头文件中的一个结构体,这是一堆标志位,就不做赘述了。

typedef struct
{
    u8 msg_id;
    u8 msg_data;
    u8 send_check;
    u8 send_version;
    u8 send_status;
    u8 send_senser;
    u8 send_senser2;
    u8 send_rcdata;
    u8 send_offset;
    u8 send_motopwm;
    u8 send_power;
    u8 send_user;
    u8 send_speed;
	u8 send_sensorsta;
    u8 send_location;
	u8 send_omv_ct;
	u8 send_omv_lt;
	u8 send_vef;
	u16 send_parame;
	u16 paraToSend;
} dt_flag_t;

接下来的代码类似于任务调度,在不同时刻将不同的代码发出。(可以忽略以下一大段代码)

/
//Data_Exchange函数处理各种数据发送请求,比如想实现每5ms发送一次传感器数据至上位机,即在此函数内实现
//此函数应由用户每1ms调用一次	
extern float ultra_dis_lpf;
void ANO_DT_Data_Exchange(void)
{
	static u16 cnt = 0;
	static u16 senser_cnt 	= 10;
	static u16 senser2_cnt 	= 50;
	static u16 user_cnt 	= 10;
	static u16 status_cnt 	= 15;
	static u16 rcdata_cnt 	= 20;
	static u16 motopwm_cnt	= 20;
	static u16 power_cnt	= 50;
	static u16 speed_cnt   	= 50;
	static u16 sensorsta_cnt = 500;
	static u16 omv_cnt = 100;
	static u16 location_cnt = 500;
	static u8	flag_send_omv = 0;

		
	if((cnt % senser_cnt) == (senser_cnt-1))
		f.send_senser = 1;

	if((cnt % senser2_cnt) == (senser2_cnt-1))
		f.send_senser2 = 1;	

	if((cnt % user_cnt) == (user_cnt-2))
		f.send_user = 1;
	
	if((cnt % status_cnt) == (status_cnt-1))
		f.send_status = 1;	
	
	if((cnt % rcdata_cnt) == (rcdata_cnt-1))
		f.send_rcdata = 1;	
	
	if((cnt % motopwm_cnt) == (motopwm_cnt-2))
		f.send_motopwm = 1;	
	
	if((cnt % power_cnt) == (power_cnt-2))
		f.send_power = 1;		
	
	if((cnt % speed_cnt) == (speed_cnt-3))
		f.send_speed = 1;		
	
	if((cnt % sensorsta_cnt) == (sensorsta_cnt-2))
	{
		f.send_sensorsta = 1;		
	}	
	
	if((cnt % omv_cnt) == (omv_cnt-2))
	{
		flag_send_omv = 1;		
	}	
	
	if((cnt % location_cnt) == (location_cnt-3))
	{
		f.send_location = 1;		
	}
	
	if(++cnt>1000) cnt = 0;
/
	if(f.send_version)
	{
		f.send_version = 0;
		ANO_DT_Send_Version(4,300,100,400,0);
	}
	else if(f.paraToSend < 0xffff)
	{
		ANO_DT_SendParame(f.paraToSend);
		f.paraToSend = 0xffff;
	}
///
	else if(f.send_status)
	{
		f.send_status = 0;
		ANO_DT_Send_Status(imu_data.rol,imu_data.pit,imu_data.yaw,wcz_hei_fus.out,(flag.flight_mode+1),flag.unlock_sta);	
	}	
///
	else if(f.send_speed)
	{
		f.send_speed = 0;
		ANO_DT_Send_Speed(loc_ctrl_1.fb[Y],loc_ctrl_1.fb[X],loc_ctrl_1.fb[Z]);
	}
///
	else if(f.send_user)
	{
		f.send_user = 0;
		ANO_DT_Send_User();
	}
///
	else if(f.send_senser)
	{
		f.send_senser = 0;
		ANO_DT_Send_Senser(sensor.Acc[X],sensor.Acc[Y],sensor.Acc[Z],sensor.Gyro[X],sensor.Gyro[Y],sensor.Gyro[Z],mag.val[X],mag.val[Y],mag.val[Z]);
	}	
/
	else if(f.send_senser2)
	{
		f.send_senser2 = 0;
		ANO_DT_Send_Senser2(baro_height,ref_tof_height,sensor.Tempreature_C*10);//原始数据
	}	
/
	else if(flag_send_omv)
	{
		flag_send_omv = 0;
		if(f.send_omv_ct)
		{
			f.send_omv_ct = 0;
			ANO_DT_SendOmvCt(opmv.cb.color_flag,opmv.cb.sta,opmv.cb.pos_x,opmv.cb.pos_y,opmv.cb.dT_ms);
		}
		else if(f.send_omv_lt)
		{
			f.send_omv_lt = 0;
			ANO_DT_SendOmvLt(opmv.lt.sta, opmv.lt.angle, opmv.lt.deviation, opmv.lt.p_flag, opmv.lt.pos_x, opmv.lt.pos_y, opmv.lt.dT_ms);
		}
	}
/
	else if(f.send_rcdata)
	{
		f.send_rcdata = 0;
		s16 CH_GCS[CH_NUM];
		
		for(u8 i=0;i<CH_NUM;i++)
		{
			if((chn_en_bit & (1<<i)))//(Rc_Pwm_In[i]!=0 || Rc_Ppm_In[i] !=0  )//该通道有值
			{
				CH_GCS[i] = CH_N[i] + 1500;
			}
			else
			{
				CH_GCS[i] = 0;
			}
		}
		ANO_DT_Send_RCData(CH_GCS[2],CH_GCS[3],CH_GCS[0],CH_GCS[1],CH_GCS[4],CH_GCS[5],CH_GCS[6],CH_GCS[7],0,0);
	}	
/	
	else if(f.send_motopwm)
	{
		f.send_motopwm = 0;
#if MOTORSNUM == 8
		ANO_DT_Send_MotoPWM(motor[0],motor[1],motor[2],motor[3],motor[4],motor[5],motor[6],motor[7]);
#elif MOTORSNUM == 6
		ANO_DT_Send_MotoPWM(motor[0],motor[1],motor[2],motor[3],motor[4],motor[5],0,0);
#elif MOTORSNUM == 4
		ANO_DT_Send_MotoPWM(motor[0],motor[1],motor[2],motor[3],0,0,0,0);
#else
		
#endif
	}	
/
	else if(f.send_power)
	{
		f.send_power = 0;
		ANO_DT_Send_Power(Plane_Votage*100,0);
	}
	else if(f.send_sensorsta)
	{
		f.send_sensorsta = 0;
		ANO_DT_SendSensorSta(switchs.of_flow_on ,switchs.gps_on,switchs.opmv_on,switchs.uwb_on,switchs.of_tof_on);
	}
	else if(f.send_location)
	{
		f.send_location = 0;
		ANO_DT_Send_Location(switchs.gps_on,Gps_information.satellite_num,(s32)Gps_information.longitude,(s32)Gps_information.latitude,123,456);
		
	}
	else if(f.send_vef)
	{
		ANO_DT_Send_VER();
		f.send_vef = 0;
	}
/
/
/
	ANO_DT_Data_Receive_Anl_Task();
/
	Usb_Hid_Send();					
/
}

接下来才是正文
以发送版本号的函数为例了解匿名飞控收发协议。
匿名飞控的通信协议
与一些较为简单的通信协议相比,这个协议增加了发送设备地址,接收设备地址,功能字,数据长度和和校验部分。其中设备地址由用户定义用来区别不同设备。功能字用来区别这一帧传输了什么内容。数据长度则是计算用户实际传输的数据长度。最后增加了一字节和校验用来校验数据。
帧格式
注意这个函数是发送用的,也就是封装这个帧

void ANO_DT_Send_Version(u8 hardware_type, u16 hardware_ver,u16 software_ver,u16 protocol_ver,u16 bootloader_ver)
{
	u8 _cnt=0;
	data_to_send[_cnt++]=0xAA;  //帧头
	data_to_send[_cnt++]=MYHWADDR; //下位机地址
	data_to_send[_cnt++]=SWJADDR;  //上位机地址
	data_to_send[_cnt++]=0x00;     //功能字,表示此帧发送版本信息
	data_to_send[_cnt++]=0;        //len字节  
	
	//以下为数据部分
	data_to_send[_cnt++]=hardware_type;
	data_to_send[_cnt++]=BYTE1(hardware_ver);
	data_to_send[_cnt++]=BYTE0(hardware_ver);
	data_to_send[_cnt++]=BYTE1(software_ver);
	data_to_send[_cnt++]=BYTE0(software_ver);
	data_to_send[_cnt++]=BYTE1(protocol_ver);
	data_to_send[_cnt++]=BYTE0(protocol_ver);
	data_to_send[_cnt++]=BYTE1(bootloader_ver);
	data_to_send[_cnt++]=BYTE0(bootloader_ver);
	
	data_to_send[4] = _cnt-5;  //计算数据长度
	
	u8 sum = 0;
	for(u8 i=0;i<_cnt;i++)    //计算校验和
		sum += data_to_send[i];
	data_to_send[_cnt++]=sum;
	
	ANO_DT_Send_Data(data_to_send, _cnt);
}

认识了这个那么其他函数都大同小异了,其中有一个函数ANO_DT_Send_RCData();较为特殊是遥控器控制的发送,之后的文章中我会提到。
另外还有一个经典的函数不得不提,这个函数是校验数据用的,也就是解帧。注释如下

void ANO_DT_Data_Receive_Prepare(u8 data)
{
	static u8 _data_len = 0;
	static u8 state = 0;
	
	if(state==0&&data==0xAA)	//校验帧头0xAA,如果state为0表明刚开始解帧,如果第一个字节的数据为0xAA,说明帧头正确。
	{
		state=1;  //如果帧头正确,state为1,可以进入下一字节
		DT_RxBuffer[0]=data;   //串口存入
	}
	else if(state==1&&data==0xAF)	//数据源,0xAF表示数据来自上位机
	{
		state=2;
		DT_RxBuffer[1]=data;
	}
	else if(state==2)		//数据目的地
	{
		state=3;
		DT_RxBuffer[2]=data;
	}
	else if(state==3)		//功能字
	{
		state=4;
		DT_RxBuffer[3]=data;
	}
	else if(state==4)		//数据长度
	{
		state = 5;
		DT_RxBuffer[4]=data;
		_data_len = data;
		DT_data_cnt = 0;
	}
	else if(state==5&&_data_len>0&&_data_len<80)
	{
		_data_len--;
		DT_RxBuffer[5+DT_data_cnt++]=data;
		if(_data_len==0)
			state = 6;
	}
	else if(state==6)
	{
		state = 0;
		DT_RxBuffer[5+DT_data_cnt]=data;
		ano_dt_data_ok = 1;//ANO_DT_Data_Receive_Anl(DT_RxBuffer,DT_data_cnt+5);
	}
	else
		state = 0;
}

如有错误还请不吝指正,欢迎交流,我的邮箱是jia_rc@163.com。

最后

以上就是潇洒自行车为你收集整理的ANO匿名飞控STM32代码解读(二)数据传输——Ano_DT.c的全部内容,希望文章能够帮你解决ANO匿名飞控STM32代码解读(二)数据传输——Ano_DT.c所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部