摘要:基于DDE(Dynamic Data Exchange)技術(shù),研究了VB6.0下組態(tài)軟件與下位機串口通信服務程序的實現(xiàn)方法,并對其進行了改進,解決了組態(tài)軟件沒有提供某些現(xiàn)場設備的通信驅(qū)動程序的問題。服務程序利用串口通信控件MSComm與下位機進行通信,同時采用DDE技術(shù)與組態(tài)軟件進行數(shù)據(jù)交換。工程實踐表明,該方法通用性強、實現(xiàn)簡便。
1、引言
在工業(yè)控制領域,組態(tài)軟件正得到越來越廣泛的使用。例如:Fix、InTouch、KingView (組態(tài)王)等均是組態(tài)軟件的優(yōu)秀代表,它們提供了豐富的工控界面、數(shù)據(jù)庫處理、對象連接等數(shù)據(jù)管理控制功能,為使用者帶來了極大的方便。組態(tài)軟件以Windows系統(tǒng)作為操作平臺,具有圖形功能完備、界面一致性好和易學易用等特點,與以往使用專用機開發(fā)的工控系統(tǒng)相比更有通用性,更方便了工程技術(shù)人員的應用開發(fā)。但在實際應用中,組態(tài)軟件常常沒能提供一些現(xiàn)場設備的通信驅(qū)動程序,而這些設備大多采用串口與PC機進行通信。
VB提供的串行通信控件MSComm,讓開發(fā)者可以方便、快捷地開發(fā)串行通信程序,而采用VB在Windows環(huán)境下實現(xiàn)符合DDE協(xié)議的通信程序也并非難事,因此整個系統(tǒng)的數(shù)據(jù)流示意圖如圖1所示。本文以組態(tài)王軟件與PHILIPS公司的51LPC系列單片機之間的通信為例,研究了采用VB6.0開發(fā)串口通信服務程序的原理及其實現(xiàn)方法。
圖1 系統(tǒng)數(shù)據(jù)流示意圖
2、串口通信的實現(xiàn)方法
Windows平臺下利用VB實現(xiàn)串口通信主要有以下兩種方法:
1)使用Windows API(Application Program Interface)函數(shù)。這種方法可編寫移植性強的通信程序,但必須首先用Declare聲明VB中所要用的動態(tài)鏈接庫DLL,這需要對Windows API函數(shù)有深入的了解,編程較復雜;
2)使用Microsoft公司提供的Active X控件MSComm。該通信控件通過改變對象屬性,向?qū)ο蟀l(fā)送消息及為對象事件編寫響應代碼,可以方便地完成用戶應用程序間的串行通信,既可實現(xiàn)API函數(shù)的所有功能,又使得編程效率提高,應用功能增強,并且程序簡單明了。
對于MSComm控件實現(xiàn)串口通信的操作很多文獻都有論述,該控件的主要屬性可參考相關(guān)文獻,在此不作具體介紹。需要強調(diào)的是:在數(shù)據(jù)發(fā)送與接收過程中,都要通過一個Variant類型變量作為中介。發(fā)送數(shù)據(jù)時,必須先將要發(fā)送的數(shù)據(jù)賦給一個Variant類型變量,再把該Variant變量賦值給MSComm的Output屬性;同樣接受數(shù)據(jù)時,也應先將MSComm的Input屬性賦值給Variant變量,待接收端收到后必須轉(zhuǎn)換成其它類型(如字符型、二進制型)的數(shù)據(jù)才能進行處理。
VB服務程序中通過串口發(fā)送數(shù)據(jù)的主要程序如下:
Private Sub TxData()
Dim Data As Byte
Dim Temp1 As Variant
Do
DoEvents ‘將CPU的控制權(quán)讓出
Loop Until Not MSComm1.PortOpen
If (Not MSComml.PortOpen) then MSComml.PortOpen=True
End if
MSComml.CommPort=l ;使用COM1口
MSComml.Setting="9600,N,8,l" ;9600
波特率,無奇偶校驗,8位數(shù)據(jù),l位停止位
Temp1= Data;利用Temp1為中介
MSComml.OutBufferCount=0 ;清除發(fā)送緩沖區(qū)
MSComml.Output=Temp1 ;發(fā)送打包后的數(shù)據(jù)
……
MSComml.PortOpen=False ;關(guān)閉串口
End Sub
下位機采用PHILIPS公司的51LPC系列單片機P87LPC769,它的基本結(jié)構(gòu)、匯編指令與80C51系統(tǒng)兼容,內(nèi)部自帶128B的RAM和4KB的OTP程序存儲器。串行口工作在模式1,數(shù)據(jù)幀信息包括1位起始位,8位數(shù)據(jù)位和1位停止位。通常設計中為了提高系統(tǒng)的抗干擾和帶負載能力以及增加通信距離,實際采用RS-485通信總線、半雙工工作方式。PC機的串口端采用RS-232/485轉(zhuǎn)換器,單片機端引腳RXD和TXD外加SN75175和SN75174。
由于現(xiàn)場可能出現(xiàn)的通信干擾,若通信失敗,系統(tǒng)將重新發(fā)送數(shù)據(jù),并統(tǒng)計次數(shù),若失敗次數(shù)超過指定次數(shù)則表明通訊失敗。另外,主機在等待下位機回答時,需要使用DoEvents函數(shù),讓出CPU的控制權(quán),以免影響組態(tài)軟件的正常運行。
3、與組態(tài)軟件的DDE通信
Windows環(huán)境下,應用程序和系統(tǒng)間以及應用程序間可通過剪貼板、動態(tài)鏈接庫DLL(Dynamic Link Library)、對象鏈接和嵌入OLE(Object Link Embedded)以及動態(tài)數(shù)據(jù)交換DDE(Dynamic Data)方便地實現(xiàn)數(shù)據(jù)的實時交換。其中,剪貼板是一種靜態(tài)交換數(shù)據(jù)的途徑,DLL不被大多數(shù)組態(tài)軟件所支持,OLE不適合串行通信方式。相比之下,DDE是一種簡單、高效又被組態(tài)軟件廣泛支持的數(shù)據(jù)交換方法。
所謂動態(tài)數(shù)據(jù)交換是指在操作系統(tǒng)環(huán)境下各個應用程序間進行實時動態(tài)數(shù)據(jù)交換。一旦提供數(shù)據(jù)的服務方改變了交換數(shù)據(jù)的內(nèi)容,接受數(shù)據(jù)的客戶方將立即自動更新交換數(shù)據(jù)內(nèi)容,從而有效地保證了數(shù)據(jù)傳送的一致性。提出交換請求的一方稱為客戶(Client),對交換請求作出響應或提供服務的一方稱為服務器(Server)。串口通信服務程序向組態(tài)軟件提供串口數(shù)據(jù)的服務,是服務器端,又稱為發(fā)送端;而組態(tài)軟件向通信服務程序發(fā)出請求,并接收其發(fā)送的數(shù)據(jù),是客戶端。
Windows應用程序間的DDE對話是通過應用程序名、主題、項目三個標識名來約定的。應用程序名(Application)是進行DDE對話雙方的名稱,KingView的程序名是View,VB的應用程序名是可執(zhí)行文件的名稱。主題(Topic)是被討論的數(shù)據(jù)域(Domain),KingView的主題被規(guī)定為TagName,VB的主題由窗體(Form)的LinkTopic屬性值指定。項目(Item)是被討論的特定數(shù)據(jù)對象,KingView中,在指定數(shù)據(jù)字典的I/O變量的同時,指定項目名稱,而在VB中,項目是一個特定的文本框、標簽或者圖片框的名稱。
為了建立兩者間的DDE連接,首先需要在組態(tài)王中定義DDE設備,DDE設備的服務程序名、主題名和數(shù)據(jù)交換方式。在組態(tài)王的數(shù)據(jù)詞典中按照預先需要通訊的變量點數(shù)和變量類型建立I/O變量,定義變量的連接設備和項目名。然后在VB程序中設置主窗體的LinkMode屬性為1,LinkTopic可任意給定,如FormDDE。另外還需定義控件的屬性和方法,設置LinkTopic、LinkItem、LinkMode三個屬性。一般的設置為:
Control.LinkTopic=服務器程序名|主題名
Control.LinkItem=項目名
Control.LinkMode=0,1,2,3
其中:0=關(guān)閉DDE,1=熱連接,2=冷連接,3=通告連接;Control為文本框、標簽框或圖片框的名字。
本文的VB服務程序中采用Text文本框控件進行DDE通訊,其設置程序主要代碼為:
Text1.LinkMode=1-Source
Text1.LinkTopic=View|TagName
這些雙方的DDE定義設置完成后,分別按先Server后Client的順序(即先啟動VB服務程序,后啟動組態(tài)王運行程序)運行應用程序后就可以實現(xiàn)VB和組態(tài)王間的DDE通訊了。
其中,將串口讀入數(shù)據(jù)發(fā)送給組態(tài)軟件的例程如下:
Privae Sub MSComml_OnComm()
Dim Temp2 As Variant
Select Case MSComm1.CommEvent
Case comEvReceive ;串口接收到數(shù)據(jù)
MSComml.InputLen=1 ;讀取一個字節(jié)
Temp2=MSComml.Input ;讀取數(shù)據(jù)
Text1.Text=CLng(Temp2) ;將數(shù)據(jù)發(fā)送給組態(tài)軟件
Case … ;其他事件處理
……
End Select
End Sub
4、對DDE通信的改進方法
實際應用中,考慮到工控軟件的數(shù)據(jù)處理能力有限,應將通信協(xié)議的轉(zhuǎn)換工作交由通信服務程序完成。串口通信服務程序根據(jù)協(xié)議提取出每一條指令或數(shù)據(jù),再將這些數(shù)據(jù)和指令同時上傳給工控軟件。工控軟件發(fā)送串口數(shù)據(jù)時,也是向通信服務程序同時發(fā)送所有的數(shù)據(jù)或指令,由通信服務程序?qū)崿F(xiàn)數(shù)據(jù)的打包發(fā)送。
為此,對VB需開辟多個Text控件,對每個控件,始終存放通信幀數(shù)據(jù)段中的固定位置的一個或多個字節(jié),如圖2所示。
圖2 控件Text與對應的數(shù)據(jù)幀示意圖
為使通信程序具有可移植性,可采用動態(tài)加載控件的辦法,即在通信程序啟動時,根據(jù)設定的幀長加載相應的Text控件數(shù)。但務必在采用變長幀的通信協(xié)議時,通信服務程序設定的幀長不應小于可能出現(xiàn)的最大幀長。
為了實現(xiàn)動態(tài)加載Text控件,需建立控件數(shù)組。這就需要在通信服務程序主窗口中添加2個Visible屬性為False的Text控件,分別命名為TextRe和TextTr,并且將這2個控件的Index
屬性都設為0之后就能在程序中用Load方法動態(tài)添加Text控件。
實現(xiàn)動態(tài)加載Text控件的程序如下:
Privae Sub Form_Load()
Dim k As Integer
Me.LinkMode=0 ;不允許DDE通信
……
If DataLen>2 Then ;DataLen存儲指定的幀長
For k=1 To DataLen/2-1 ;每條指令占2個字節(jié)
Load TextRe(k)
Load TextTr(k)
Next k
End If
Me.LinkMode=l ;允許DDE通信
End Sub
5、結(jié)束語
VB是一種成熟的、面向?qū)ο蟮某绦蛟O計語言,采用它編寫的Windows環(huán)境下PC機與下位機的串行通訊軟件具有程序?qū)崿F(xiàn)簡便、通用性強的特點,減輕了軟件開發(fā)者的工作量。本文利用VB的串行通信控件MSComm,并采用DDE技術(shù)較好地實現(xiàn)了上位PC機中組態(tài)王軟件與下位單片機間的雙向通信。組態(tài)軟件編寫的上層人機監(jiān)控界面直觀、友好。實際運行證明該串行通訊服務程序方便可靠,具有較強的實用價值。