實現單片機與PC機多機通訊的程序
實現功能是這樣的:
用調試助手向單片機發送一個數據包。
通訊協議是這樣的:
數據包的格式如下所示(共10個字節組成):
0x2A,0xEB,0x8D,地址碼,指令碼,數據長度碼,數據碼,數據碼,校驗碼,0xAD
前面三個字節為幀頭,即開始符。
地址碼: 欲傳送的目的地址,即選定哪一個單片機。
指令碼:向單片機發送的指令
數據長度碼: 用于指示后面有效數據的個數
數據碼:傳送的數據,配合指令碼的純數據。
校驗碼: 累加和校驗,對地址碼,指令碼,數據長度碼,數據碼進行累加,用來檢驗數據的完整性和正確性。
0xAD : 幀尾,即結束符。
本程序實現功能是這樣的:
用調試助手向單片機發送一個數據包,單片機收到后對數據解析,再回傳指定的數據。
例如發送:2a eb 8d 01 03 01 01 06 ad
指令碼為01,單片機接收到后解析,回傳0xce 0x7b 0x11 0xed。其中前兩個字節為開始符,最后一個字節為結束符。同理,若收到的指令碼為02,回傳0xce 0x7b 0x12 0xed。以此模擬控制單片機操作。
若接收錯誤,即累加校驗碼不等于單片機實際計算的累加和,回傳0xce 0x7b 0x02 0xed,提示接收錯誤,要求PC重發數據(模擬,需要上位機軟件配合才行)。
單片機開機初始化后即向PC發送一個數據0xce 0x7b 0x00 0xed,用于指示單片機與PC通信已連接。
下面是程序:
#define ID 0x01 //單片機地址
uint8 rec_data; //串口通信接收數據
uint8 state_flag=0; //通信協議解析狀態標志,初始化為0
uint8 retval=0; //通信協議解析函數返回值,初始化為0
uint8 cmd; //指令碼
uint8 Data[2]; //數據碼
uint8 data_count; //數據長度碼
程序大體思想是:
首先定義了幾個全局變量,接收到數據后,串口中斷子程序中用變量rec_data存儲一個字節的數據,隨后對數據進行解析:首先判斷數據包的完整性,正確性,然后提取指令碼,數據碼等數據,存放起來用于主程序處理。
協議解析過程中,使用一個變量state_flag的全局變量作為協議解析狀態標志,用于確定當前字節處于一幀數據中的那個部位,同時在接收過程中自動對接收數據進行校驗和處理,在數據包接收完的同時也進行了校驗的比較。因此當幀尾結束符接收到的時候,則表示一幀數據已經接收完畢,并且也通過了校驗,關鍵數據也保存到了緩沖區(cmd和Data[])中。主程序即可通過查詢retval的標志位來進行協議的解析處理。如果retval=1; //錯誤標志,數據包傳送不正確。如果retval=2; //接收成功標志,數據包傳送成功。
接收過程中,只要哪一步收到的數據不是預期值,則直接將狀態標志復位,用于下一幀數據的判斷,避免狀態自鎖。
以下是程序:
void PortInit(); //各端口初始化
void TimerInit(); //定時器初始化
void UsartInit(); //串口初始化
void usart_cmd_scan(); //串口命令掃描
void Data_analysis(); //通信協議解析函數
void Send(uint8 sendcmd); //數據發送函數
/*-------------------------------- 串口中斷服務子程序 ------------------------------------*/
void ser() interrupt 4
{
RI=0;
rec_data=SBUF; //讀取接收到的數據
Data_analysis();//數據解析
}
/*
* 函數名:Data_analysis
* 描 述:通信協議解析函數
* 輸 入:無
* 輸 出:無
* 備 注:解析串口接收到的數據


評論