我使用代码对应的上位机版本为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 == 8ANO_DT_Send_MotoPWM(motor[0],motor[1],motor[2],motor[3],motor[4],motor[5],motor[6],motor[7]);
#elif MOTORSNUM == 6ANO_DT_Send_MotoPWM(motor[0],motor[1],motor[2],motor[3],motor[4],motor[5],0,0);
#elif MOTORSNUM == 4ANO_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);}elsestate = 0;
}

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

ANO匿名飞控STM32代码解读(二)数据传输——Ano_DT.c相关推荐

  1. ANO匿名飞控STM32代码解读(一)任务调度——Ano_Scheduler.c

    我所学习的代码是匿名飞控使用STM32芯片ANO_PioneerPro-20190825的版本. 匿名飞控的整体代码是跑裸机的,任务调度是用STM32F4芯片中的系统时钟计时,做了一个任务调度系统,举 ...

  2. ANO匿名飞控分析(2)— 任务调度

    准备电赛,简单写一下匿名飞控的分析 基于TM4C主控的匿名拓空者飞控,介绍见匿名科创–匿名拓空者PRO-TI版全开源飞控使用入门-TM4C123 一.简介 匿名飞控的任务调度还是比较简单的,没有操作系 ...

  3. 匿名飞控STM32版代码整理之Ano_Imu.c

    一.ANO_Imu.c文件 /******************** © COPYRIGHT 2016 ANO Tech *************************** 作者 :匿名科创 文 ...

  4. STM32学习心得二十一:实时时钟RTC和备份寄存器BKP特征、原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容 1) RTC特征与原理: 2) BKP备份寄存器特征与原理: 3) RTC常用寄存器+库函数介绍: 4) 相关实验代码解读. 实验内容: 因为没有买LCD屏,所以计 ...

  5. 2021-05-24匿名凌霄飞控代码解读Drv_AnoOf.c和LX_FC_EXT_Sensor.c

    5.24:匿名凌霄飞控代码解读Drv_AnoOf.c和LX_FC_EXT_Sensor.c 注意:两部分的代码结合读,先看懂AnoOf.c然后再看对光流数据处理的文件Sensor.c 1.Drv_An ...

  6. ANO匿名上位机V7协议STM32

    ANO匿名上位机V7协议&STM32 说明:以下程序为自己编写,若有误欢迎各位指出. 基于ANO匿名V7上位机的通信协议编写的代码 文章目录 ANO匿名上位机V7协议&STM32 前言 ...

  7. STM32学习心得十九:电容触摸按键实验及相关代码解读

    记录一下,方便以后翻阅~ 主要内容 1) 电容触摸按键原理: 2)部分实验代码解读. 实验内容 手触摸按键后,LED1灯翻转. 硬件原理图 上图,TPAD与STM_ADC用跳线帽相连,即TPAD与PA ...

  8. STM32学习心得十八:通用定时器基本原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容: 1) 三种定时器分类及区别: 2) 通用定时器特点: 3) 通用定时器工作过程: 4) 实验一:定时器中断实验补充知识及部代码解读: 6) 实验二:定时器PWM输 ...

  9. Jsoup代码解读之二-DOM相关对象

    转载自  Jsoup代码解读之二-DOM相关对象 之前在文章中说到,Jsoup使用了一套自己的DOM对象体系,和Java XML API互不兼容.这样做的好处是从XML的API里解脱出来,使得代码精炼 ...

最新文章

  1. ERROR: Failed to resolve: com.android.support:appcompat-v7:29.0.0
  2. ipvs-dr模型及算法、keepalived基本应用、keepalive+ipvs实现高可用
  3. JAVA入门[17]-ControllerAdvice处理exception
  4. pytorch 查看gpu cuda版本
  5. 【Android工具】wifi概观360中文专业版,wifi overview 360 pro,wifi信息查看工具
  6. VUE:class与style强制绑定
  7. 删除已使用过且无法删除的替代
  8. git gui管理服务器配置文件,从 Git Gui 管理的Repository(库) 提交更改到 Bonobo服务器管理的Repository(库)...
  9. 数据可视化,带给你的惊艳并不止这一点!
  10. 老师 累了,我们 泪了!
  11. dojo 官方翻译 dojo/json 版本1.10
  12. python写ini文件不能保持原有顺序问题_python 生成 xml文件 属性的顺序问题
  13. Java获取当前Linux系统ip,cpu和内存使用情况,进程信息并保存至数据库
  14. centos7安装RabbitMQ详细过程
  15. SplitContainer控件扩展之收缩面板
  16. 洋流[Theocean flow]介绍----科普知识
  17. java ext_ext下载及使用
  18. wd 文件服务器客服电话,wd 云服务器
  19. 一天一看————计算机网络参数模型与5G协议!
  20. 倒计时2天 校园行|AI TIME “未来杯” 走进浙江大学

热门文章

  1. MySQL的索引是如何实现的
  2. Ubuntu 16.04 中文输入法(搜狗输入法)安装记录
  3. Windows PE研究
  4. 从PD充电器取9V12V给产品供电快充,PD取电芯片概述
  5. PLC控制电动机的顺序启动逆序停止
  6. python数据清洗--对双十一淘宝直播流量数据进行数据真实性验证
  7. Linux 的父进程和子进程的执行情况(附有案例代码)
  8. 镂空三角形(for循环找规律)
  9. lua web快速开发指南(7) - 高效的接口调用 - httpc库
  10. selenium 批量下载qq邮箱附件