要利用上位机显示波形数据,就必须按照上位机给定的数据格式来编写单片机传输数据的格式,其实质就是串口发送数据包的格式。
用此上位机发波形数据的格式,可总结成:帧头+功能字+长度+数据+校验
。匿名提供了一些特殊的功能字用于飞控数据的传输。我们这里采用高级收码。帧头是AAAA
,功能字是F1到FA
, 这十个功能字对应十个用户自定义的数据类型,其他特定类型数据(如pid参数)有其对应的功能字。
基本步骤:(1)使用某帧,需要勾选使能该帧并保存。
(2)用户数据格式需要根据程序中的数据格式进行选择。
(3)设置数据容器。什么是数据容器呢,就是刚才F1数据帧进行解析后,会解析出最多30个数据,用哪个数据进行波形显示呢,这就需要配置数据容器了。匿名上位机设置有20个数据容器,对应1到20选项卡。我们可以把数据容器想象成20个卡车,只有卡车能将数据传输到用户,那么这20辆卡车将哪个数据传输给用户呢,就需要配置图中的数据来源和位置了。首先选择数据来源,帧1到帧10,对应F1到FA数据帧,然后是数据位置,有1到30共30个选项,分别对应数据帧内包含的30个数据。
具体配置比如:
我们想传输3个自己的数据到上位机进行显示,第一个为uint16型,第二个为uint8型,第三个为int16型。
第一步:我们可以用F1到FA任意一个用户自定义数据帧,以F1为例,勾选使能该帧,显示该帧,然后右方第一行依次选择我们需要的3个数据类型,分别为uint16,uint8,int16。其余后续的数据类型不作更改,任意值都可,最后点击保存设置。
第二步:对数据容器进行配置,容器1设置为:数据来源:帧1,数据位置:1;容器2设置为:数据来源:帧1,数据位置:2;容器3设置为:数据来源:帧1,数据位置:3。此时,数据容器1、2、3就分别存放了我们需要的3个数据。
配置完上位机,再来编写下位机程序(此处发送两个数据,一个uint16和一个uint8型):
//数据拆分宏定义,在发送大于1字节的数据类型时,比如int16、float等,需要把数据拆分成单独字节进行发送
#define BYTE0(dwTemp) ( ( (char )(&dwTemp) ) )
#define BYTE1(dwTemp) ( ( (char )(&dwTemp) + 1) )
#define BYTE2(dwTemp) ( ( (char )(&dwTemp) + 2) )
#define BYTE3(dwTemp) ( ( (char )(&dwTemp) + 3) )
u8 datato_send[50]; //发送数据缓存
void ANO_Send_Byte(u8 data_to_send[], u8 _cnt)
{
int i;
for (i = 0; i < _cnt; i++)
Usart_SendByte(USART1, data_to_send[i]);
}
void ANO_DT_Send_Data(u8 fun,u16 data1,u8 data2)
{
u8 _cnt=0,sum = 0,i;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xAA; //AAAA为帧头
data_to_send[_cnt++]=fun; //此处为功能字,对应F1-FA(自定义帧)
data_to_send[_cnt++]=0; //本字节表示数据长度,这里先=0,函数最后再赋值,这样就不用人工计算长度了_
data_to_send[_cnt++]=BYTE1(data1); //int16 需要拆分成单字节
data_to_send[_cnt++]=BYTE0(data1);
data_to_send[_cnt++]=data2; //u8不用拆分 **拆分只是为了发送,上位机如果收到uint16是收到完整的数据,因而在帧格式设置里只需要将第一个数据位置选为uint16
data_to_send[3] = _cnt-4; //长度字节:表示该数据帧内包含数据的字节总长度,不包括帧头、功能字、长度字节和最后的校验位。
for(i=0;i<_cnt;i++)**
sum += data_to_send[i];
data_to_send[_cnt++]=sum; //校验位
ANO_Send_Byte(data_to_send, _cnt);
}
然后发送波形数据时调用 ANO_DT_Send_Data该函数即可。
(具体usart配置省略)