这个软件不仅仅可以用在调试飞机上面,平时用他来看一个数据波形什么的,也是非常有用的。

之前用他看单独的6050数据,过了一段时间就忘记了怎么用的,所以就浪费了很多时间再次学习,今天就记录下来。

要想实现单片机与上位机的通信,就要按照上位机给定的数据格式来编写传输数据的格式。其实质就是串口发送数据包的格式。

在上位机的界面上就能找到数据格式的说明:

这是我使用的版本。

按照他给定的格式,我们可以这样打包数据(89C52单片机版本,32上也能用):

/******************************************
** 说明:
    1、 发送给上位机的数据帧定义 
        @桢头--功能字--长度--数据(一个或多个,具体看协议说明)-校验
        @前2个字节为帧头0xAAAA 
        @第3个字节为帧ID,也就是功能字,应设置为0xF1~0xFA中的一个 
        @第4个字节为报文数据长度(dlc) 
        @第5个字节开始到第5+dlc-1个字节为要传输的数据内容段,每个数据场为高字节在前,地字节在后 
        @第5+dlc个字节为CheckSum,为第1个字节到第5+dlc-1个字节所有字节的值相加后,保留结果的低八位作为CheckSum 
    2、 外部直接调用这个函数。
    3、 需要在此文件中引用需要发送的其他文件中的数据。
    4、 发送的数据必须是 int_16 型的数据
*****************************************/  
void uart_send_senser(void)
{
    unsigned char  xdata data_to_send[23] = {0};
    unsigned char i = 0;
    unsigned char cnt = 0;
    unsigned char sum = 0;

    int int_set_distance_2 = (int)set_distance_2;
    int int_real_distance = (int)real_distance;
    int int_ASR_output = (int)ASR.output;
    

    data_to_send[cnt++]=0xAA;     //帧头:AAAA
    data_to_send[cnt++]=0xAA;
    data_to_send[cnt++]=0x02;     //功能字:OXFn只接受数据,不显示图像。0x0n显示数据和图像
    data_to_send[cnt++]=0;         //需要发送数据的字节数,暂时给0,后面在赋值。

    data_to_send[cnt++] = BYTE1(int_set_distance_2);    //高字节
    data_to_send[cnt++] = BYTE0(int_set_distance_2);    //低字节
    data_to_send[cnt++] = BYTE1(int_real_distance);
    data_to_send[cnt++] = BYTE0(int_real_distance);
    data_to_send[cnt++] = BYTE1(int_ASR_output);
    data_to_send[cnt++] = BYTE0(int_ASR_output);

    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;

    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;
    data_to_send[cnt++] = 0;

    data_to_send[3] = cnt-4;//计算总数据的字节数。

    for(i=0;i<cnt;i++) //对于for语句,当不写大括号的时候,只执行到下面第一个分号结束。
    {
        sum+=data_to_send[i];
    }

    data_to_send[cnt++] = sum;    //计算校验位
    uart_send_string(data_to_send,cnt);

}

其中那个BYTE()函数就是按照协议写的数据类型转换。

/**********为了匿名四轴上位机的协议定义的变量****************************/
//cup为小端模式存储,也就是在存储的时候,低位被存在0字节,高位在1字节
#define BYTE0(dwTemp)       (*(char *)(&dwTemp))     //取出int型变量的低字节
#define BYTE1(dwTemp)       (*((char *)(&dwTemp) + 1))     //    取存储在此变量下一内存字节的内容,高字节
#define BYTE2(dwTemp)       (*((char *)(&dwTemp) + 2))
#define BYTE3(dwTemp)       (*((char *)(&dwTemp) + 3))

单片机的程序写好了,下一步就是设置上位机中数据的接收方式。上图:

根据自己定义的数据包的大小,其实就是数组的长度,最多可以发送20个数据。

数据设置好之后,打开串口,选择波特率,在高级收码里面看自己的数据是否符合格式。

最后一部观察数据波形

 

这篇博客也有说明:http://bbs.elecfans.com/jishu_536667_1_5.html

 

题外话:

在用51单片机与上位机进行串口通信的时候,波特率是个问题。这时可以使用89C52系列的定时器2作为波特率发生器。但是要特别注意自己晶振的选择,这个细节让我找了好久。

/* ********************************************************
** 作者 :Andrew
** 日期    :2018.3.11    
** 说明 :
    1、使用定时器2做波特率发生器,11.0592M晶振,可以产生115200的波特率
    2、使用85C52系列的单片机时,一般P3.1-TXD,   P3.0-RXD ,且与USB共地。
    3、115200波特率的时候,必须使用11.0592的晶振,12M的不行,这个细节让我找了半天的bug。发疯ing 
    4、12M晶振时的波特率最好时4800,误差最小。                      
******************************************************** */
void uart_init()
{
    SCON = 0X50;              //SCON:串行口工作方式1, 8-bit UART,允许串行接收位(REN=1)
    TH2 = RCAP2H = 0XFF;       //baud : 115200
    TL2 = RCAP2L = 0XFD;       //0xdc 为9600 baud       ,0XFD为115200 baud
    T2CON = 0X34;            //控制寄存器,可设置三种工作模式:捕获、计数器、波特率发生器
    IE = 0X90;              //IE中断允许寄存器,0x90是开总中断和串口中断。
         
}

 

 

版权声明:本文为qsyll0916原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/qsyll0916/p/8543745.html