匿名上位機的使用(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是開總中斷和串口中斷。
         
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM