• 匿名上位机的使用(51版)


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

    之前用他看单独的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是开总中断和串口中断。
             
    }

  • 相关阅读:
    洛谷P1175 表达式的转换
    洛谷P1725 琪露诺
    bzoj1047 [HAOI2007]理想的正方形
    洛谷P1886 滑动窗口
    最大数的和
    bzoj1087 [SCOI2005]互不侵犯King
    bzoj1051 [HAOI2006]受欢迎的牛
    Android(java)学习笔记41:Map集合功能概述
    Android(java)学习笔记40:WindowManager 中LayoutParams的各种属性
    Android(java)学习笔记39:Android 修改字体
  • 原文地址:https://www.cnblogs.com/qsyll0916/p/8543745.html
Copyright © 2020-2023  润新知