本文章首先呢,需要介绍一下该文章使用到哪些内容:MDK5、山外调试助手、匿名上位机、STM32F1、MPU6050、杜邦线、下载器,程序、山外调试助手以及匿名上位机在结尾附录
匿名上位机:一款功能十分完备的上位机软件,支持基本的串口的收发、波形展示、GPS信息、飞控状态、自定义协议等等,在这里主要用到的是飞控状态功能,如下图
该飞控状态功能可以实现把MPU6050六轴陀螺仪的姿态以更加直观的方式进行展示出来,方便数据分析
MPU6050六轴陀螺仪:这一部分麻烦劳驾看我上一篇文章,是主要介绍该模块的,这里附上链接,就不在赘述
https://blog.csdn.net/weixin_42193239/article/details/102979420
下面进入正题,首先介绍一下上位机的基本原理,通常来说一个上位机最基本的功能就是实现串口或其它方式的数据收发,其它一切的功能都是基于基本收发来实现的
数据校验:假设我们需要通过下位机来向上位机发送温度数据,该数据为uint类型,大小为0-65535.,长度2字节,那么问题就来了,串口只能一次接收一个字节的内容,也就是0-255,但是我们想发送的是uint类型,这怎么办呢?
一般来说需要将16位的数据进行分开,先发送高八位再发送低8位,如下图
uint temp;//温度数据
uchar temp_H,temp_L;//定义高八位和第八位
temp = 0xf1c7;// 1111 0001 1100 0111
/*但是串口一次只能发送一个字节,这里需要拆开*/
temp_H = temp >> 8;//向右移动八位,默认保留后八位 1111 0001
temp_L = temp & 0x0f;//将左侧八位清空,默认保留后八位 1100 0111
将数据分开进行发送,在上位机部分通过拼合,把两个uchar类型转化成一个uint类型,但是如果此时数据里丢失一位,即第一次数据的高八位与第二次数据的高八位被上位机拼合了,数据类型没错,上位机是检测不出来的,这就造成数据严重错乱 。
为了解决这种情况就引入了帧的概念,一帧数据包括帧头和结尾,常见的一帧数据的帧头是固定几位的不常用数据,告诉下位机我要发送数据了(这里以匿名上位机的协议为例)
如图,帧头为 AAAA,即 0xAA 0xAA,功能字0x01,是第三位,后面依次是总数据长度LEN,以及数据,在本帧中数据包括三个int 类型 一个int32 和两个 u8类型,一共是12个数据,所以LEN = 0x0C,最后的校验是对所有内容相加的校验,匿名给出的结束是前十六位数据相加取后两位为校验
/*这里以一个短帧为例子进行说明*/
//假设一帧数据2位,帧头为0xEE 结尾为sum 校验位
//EE F2 C3 sum]
//在该系统中,sum = 0xee + 0xf2 + 0xc3 = 2A3
//取后两位 sum = A3
//所以完整的数据为 ee f2 c3 a3
通过上面的例子,可以理解校验数据的作用,即防止数据错了造成影响,加入了帧头和校验位的概念
波形显示:这里主要针对山外上位机来进行解释,波形显示的本质就是在一个固定的时间间隔内建立坐标然后进行连线,对于上位机的波形来说,这个时间取决于你发数据的频率,假设你分三次分别发送 0x01,0x02,0x03,那么在坐标里得出的形状是一条直线,同时每次发送的数据也需要进行校验来保证数据正确
上面是山外上位机对虚拟示波器功能进行的官方解释和使用说明(匿名上位机似乎只能使用它内置的变量进行波形显示,所以此处以山外调试助手为例)
飞控状态:这部分为该文章主要介绍内容,通过查看匿名上位机的协议手册与软件界面,该四轴的空间状态是由三个变量来控制的,分别是
对应的协议部分为:
就是上面介绍的数据帧格式,此时我们在stm32中进行代码编译:
/*************************************
//完成时间:2019年11月18日 12:03:32
//功能介绍:实现匿名上位机飞控状态反映陀螺仪数据
//制作:程皖
//联系方式:QQ:110662822
***************************************/
/*************************************
A_X:X轴数据 -90-90
A_Y:Y轴数据
A_Z:Z轴数据 -90-90
***************************************/
extern short T_X,T_Z,T_Y;
extern short A_X,A_Z,A_Y;
unsigned char ANO_BUFF[17];
/*************************************
函数名称:void Send_FLY();
功能介绍:根据匿名协议向上位机发送下位机姿态
***************************************/
void Send_FLY()
{
unsigned i,sum;
READ_MPU6050();
ANO_BUFF[0] = 0xAA;
ANO_BUFF[1] = 0xAA;
ANO_BUFF[2] = 0x01;
ANO_BUFF[3] = 0x0C;
ANO_BUFF[4] = A_X>>8;
ANO_BUFF[5] = A_X<<8;
ANO_BUFF[6] = A_Z>>8;
ANO_BUFF[7] = A_Z>>8;
A_Y = A_Y * 10;
ANO_BUFF[8] = A_Y>>8;
ANO_BUFF[9] = A_Y>>8;
ANO_BUFF[10] = 0x00;
ANO_BUFF[11] = 0x00;
ANO_BUFF[12] = 0x00;
ANO_BUFF[13] = 0x00;
ANO_BUFF[14] = 0x00;
ANO_BUFF[15] = 0x01;
sum = 0;
for(i=0;i<16;i++)
{
sum=ANO_BUFF[i]+sum;
}
ANO_BUFF[16] = sum;
for(i=0;i<17;i++)
{
sendByte(USART1,ANO_BUFF[i]);
}
}
编写该协议部分的串口发送代码,MPU6050数据获取在这里不再详细介绍,此时我们上电验证
程序代码:链接: https://pan.baidu.com/s/1KkeXbbwyTEEE8MJmzAZ1_w 提取码: zjhd