1. 程式人生 > >匿名上位機的使用(51版)

匿名上位機的使用(51版)

height init checksum water 允許 飛機 OS HA 引用

這個軟件不僅僅可以用在調試飛機上面,平時用他來看一個數據波形什麽的,也是非常有用的。

之前用他看單獨的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是開總中斷和串口中斷。
         
}

匿名上位機的使用(51版)