劉智慧
(西安外事學(xué)院 計(jì)算機(jī)中心,陜西 西安710077)
隨著計(jì)算機(jī)的發(fā)展,單片機(jī)在工業(yè)控制領(lǐng)域里得到廣泛的應(yīng)用,例如:用于數(shù)據(jù)采集、監(jiān)控與控制等。很多工業(yè)控制系統(tǒng)都采用上下位機(jī)的方式,用串口來實(shí)現(xiàn)數(shù)據(jù)交換。為了實(shí)現(xiàn)上位機(jī)與下位機(jī)之間快速、高效的通信,這就需要根據(jù)兩者之間的通信協(xié)議在上位機(jī)和下位機(jī)編寫相應(yīng)的串口通信程序,本文主要是針對上位機(jī)串行通信的設(shè)計(jì)和實(shí)現(xiàn)。
在Windows環(huán)境下,既可以用Windows API函數(shù)進(jìn)行串行通信編程,也可以利用串行通信控件來進(jìn)行編程。利用API函數(shù)編寫實(shí)際應(yīng)用程序時(shí),往往要考慮多線程的問題,這樣編出來的程序龐大,且結(jié)構(gòu)復(fù)雜,繼承性差,維護(hù)困難。使用串行通信控件就相對簡單一些,而且其功能強(qiáng)大,性能安全可靠。Comport控件庫中就提供了串行通信控件。另外用Delphi編寫圖形用戶界面程序比較容易,所以用Delphi+ComPort控件庫進(jìn)行串行通信程序的設(shè)計(jì)不失為一個明智的選擇[1]。
ComPort 控 件 庫 適 用 于 Win95、Win98、WinNT、Windows2000、Windows XP等操作系統(tǒng),支持 Delphi3~7和 C++Builder3~6, 有 TComPort、TComDataPacket、TComComboBox、TComRadioGroup、TComLed、TComTerminal等控件 (其中的TComPort提供的功能就類似于MSComm),支持同步、異步讀寫操作,可對流控制進(jìn)行詳細(xì)的設(shè)置,可以設(shè)置讀寫操作的超時(shí)(TimeOut)時(shí)間,用多線程監(jiān)視串口事件[2]。
TComDataPacket可以很容易從輸入緩沖區(qū)中以包的形式讀出數(shù)據(jù),并且可以通過設(shè)定TComDataPacket的屬性來設(shè)定數(shù)據(jù)包的開始和終止條件。
TComTerminal可以接收TComPort控件接收到的數(shù)據(jù)并顯示在屏幕上。它支持VT52,VT100和ANSI等終端連接。
TComComboBox提供可視化用戶界面,使用戶可以很容易地設(shè)置串口的常用屬性,并可以選擇所需要的串口。
TComLed可以顯示CTS,DSR,RLSD,Ring,Tx和Rx等信號的狀態(tài)。TComLed可以與 TComPort連接,當(dāng)這些串口信號變化的時(shí)候,TComLed就可以自動地更新這些信號的狀態(tài)。
本文中就是利用TComPort控件實(shí)現(xiàn)PC機(jī)(上位機(jī))與伺服控制器(下位機(jī))之間的串行通信。
串口的讀寫操作可以以2種方式進(jìn)行:同步或者異步。在同步方式下,進(jìn)行串口操作的函數(shù)直到操作完成或者產(chǎn)生錯誤才返回。在異步方式下,進(jìn)行串口操作的函數(shù)執(zhí)行后直接返回,無需等待操作結(jié)束。在進(jìn)行異步操作后,如果執(zhí)行的結(jié)果還沒有出來,所有應(yīng)用程序應(yīng)該調(diào)用等待函數(shù)(Wait)以確保操作完成。在異步操作和等待函數(shù)(Wait)之間,應(yīng)用程序可以執(zhí)行與此異步操作結(jié)果無關(guān)的其他任何操作[3]。
在執(zhí)行異步操作之前要先調(diào)用InitAsync方法,該方法是初始化PAsync類型的參數(shù),每個進(jìn)行異步操作的方法都有PAsync參數(shù)。在操作完成后,調(diào)用DoneAsync方法釋放資源。
ComPort控件有很多重要的屬性、方法和事件,通過這些可以很好地控制串口。常用的屬性方法和事件[4-5]如下:
1)常用屬性 ①BaudRate、Port、DataBits、Parity、StopBits:
分別設(shè)置串口的波特率、對應(yīng)的串口號、數(shù)據(jù)位、校驗(yàn)類型和校驗(yàn)位、停止位;②Buffer:設(shè)置接收、發(fā)送緩沖區(qū)的大?。虎跜onnected:返回串口的狀態(tài);也可以打開或者關(guān)閉串口;④FlowControl:設(shè)置流的控制方式;⑤Timeouts:用來設(shè)置讀寫操作的間隔和完成的超時(shí)時(shí)間;⑥TriggersOnRxChar:用來設(shè)置當(dāng)串口接收到數(shù)據(jù)的時(shí)候,哪個事件會被觸發(fā)(On-RxBuf還是 OnRxChar),通常設(shè)置 TriggersOnRxChar=True,也就是串口接收到數(shù)據(jù)時(shí)候,觸發(fā)OnRxChar事件。
2)常用方法和事件 ①Open/Close:打開/關(guān)閉串口;②Read/ReadStr:向串口讀字符/讀字符串;③Write/WriteStr:向串口寫字符/寫字符串;④OnRxChar:當(dāng)串口接收到數(shù)據(jù)時(shí),觸發(fā)該事件。
ComPort提供了2種讀串口數(shù)據(jù)的方式:事件驅(qū)動方式和查詢方式。
1)事件驅(qū)動方式 用事件驅(qū)動方式對串口操作,響應(yīng)速度快,可靠性高,是一種有效的方式。當(dāng)有串口接收到數(shù)據(jù)的時(shí)候,會觸發(fā)ComPort控件的OnRxChar事件,就可以在這個事件中寫處理數(shù)據(jù)的代碼。
2)查詢方式 查詢方式就是在需要讀取數(shù)據(jù)時(shí),用Com-Port提供的Read或者ReadStr函數(shù)讀串口以獲得接收到的數(shù)據(jù)。
在電機(jī)伺服控制器的課題中,PC機(jī)作為上位機(jī),通過串行口與多個用MCU實(shí)現(xiàn)的下位機(jī)進(jìn)行通信,示意圖如圖1所示。
圖1 上位機(jī)與下位機(jī)通信示意圖Fig.1 Schematic diagram of communication between PC and MCU
用Delphi6編寫上位機(jī)的控制程序,用來控制下位機(jī)。上位機(jī)和下位機(jī)之間發(fā)送的數(shù)據(jù)格式如圖2所示。
圖2 數(shù)據(jù)格式Fig.2 Data format
每包數(shù)據(jù)的大小最少為4個字節(jié):指令字(2字節(jié));數(shù)據(jù)長度(1 字節(jié));數(shù)據(jù)字(0 字節(jié));校驗(yàn)值(1 字節(jié))。
MCU每收到第3個字節(jié)(數(shù)據(jù)長度)后,由“數(shù)據(jù)長度”字節(jié)確定數(shù)據(jù)字的長度和校驗(yàn)值。校驗(yàn)值是從指令字的第1個字節(jié)到校驗(yàn)值之前字節(jié)的異或值。判斷計(jì)算得到的校驗(yàn)值與收到的校驗(yàn)值是否一致,一致則發(fā)送回應(yīng)信息——數(shù)據(jù)已正常接收;否則不回應(yīng)。
在ComPort控件的屬性欄中設(shè)置串口的主要屬性:BaudRate:=br9600;DataBits:=dbEight。 然后在“打開串口”按鈕的Click事件中打開串口,打開串口的偽代碼如下:
在下面的代碼中aCommandType表示上位機(jī)發(fā)給下位機(jī)的是地址幀 (TI_Address)、讀取數(shù)據(jù)的命令幀(TI_Command)還是發(fā)送給下位機(jī)的數(shù)據(jù)幀(TI_Data)。
首先上位機(jī)發(fā)送讀取數(shù)據(jù)的命令幀給MCU,這個命令幀包括要讀取的參數(shù)代碼。命令幀的具體格式由PackData()函數(shù)實(shí)現(xiàn),通信協(xié)議不同,PackData(CommandType:TInfo-Type)函數(shù)的實(shí)現(xiàn)也不同,讀取下位機(jī)數(shù)據(jù)的偽代碼[6]如下:
在下面的事件中接收下位機(jī)返回的數(shù)據(jù):
其工作原理與從下位機(jī)讀取數(shù)據(jù)類似,向下位機(jī)發(fā)送數(shù)據(jù)的偽代碼如下:
通過上位機(jī)和一個下位機(jī)進(jìn)行串行通信試驗(yàn),上位機(jī)成功獲得了伺服控制器(下位機(jī))的狀態(tài)(伺服電機(jī)的速度、轉(zhuǎn)矩和位置偏差等),如圖3所示。
圖3 上位機(jī)與下位機(jī)通信獲得的數(shù)據(jù)繪制成的波形圖Fig.3 Graph of MCU status(PC got data from MCU by serial communication)
結(jié)合實(shí)際項(xiàng)目,利用第三方控件庫CPort中的控件ComPort在Windows下實(shí)現(xiàn)了PC機(jī)與單片機(jī)的串行通信,并給出了部分實(shí)現(xiàn)代碼及結(jié)果。此方案在實(shí)際運(yùn)行過程中,實(shí)現(xiàn)了上位機(jī)與下位機(jī)之間的通信。本文中給出的只是CPort控件庫中的ComPort控件的應(yīng)用,CPort控件庫中還有其他的控件,如 ComLed,TComDataPacket,TcomTerminal等,可以幫助用戶很容易地實(shí)現(xiàn)串口通信相關(guān)的其他復(fù)雜的應(yīng)用程序。
[1]范逸之,陳立元.Delphi與RS-232串行通信控制[M].北京:清華大學(xué)出版社,2002.
[2]趙蘭濤,蘇彥華.Delphi串口通信技術(shù)與工程實(shí)現(xiàn)[M].北京:人民郵電出版社,2004.
[3]趙曙光.Delphi中利用ComPort元件開發(fā)串行通信程序[J].應(yīng)用科技,2001,28(3):15-16.ZHAO Shu-guang.Development of ComPort by use of Com-Port component in Delphi[J].Applied Science and Technology,2001,28(3):15-16.
[4]張程志.基于ComPort Library控件的Delphi串行數(shù)據(jù)采集系統(tǒng)的軟件設(shè)計(jì)[J].水利科技與經(jīng)濟(jì),2007,13(8):614-615.ZHANG Cheng-zhi.Computer series-port communication technology based on ComPort Library and XSL/B intelligent digital apparatus[J].Water Conservancy Science and Technology and Economy,2007,13(8):614-615.
[5]張秀德.基于ComPort Library的Delphi串行數(shù)據(jù)采集系統(tǒng)的軟件設(shè)計(jì)[J].工業(yè)控制計(jì)算機(jī),2004,17(12):53-54.ZHANG Xiu-de.Delphi software design of serial data acquisition system based on comport library[J].Industrial Control Computer,2004,17(12):53-54.
[6]席一凡.Delphi程序設(shè)計(jì)[M].北京:中國鐵道出版社,2008.