匿名上位機的使用(51版)
阿新 • • 發佈:2018-03-11
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版)