文獻標(biāo)識碼: A
文章編號: 0258-7998(2011)11-0144-03
目前,工業(yè)組態(tài)軟件已經(jīng)廣泛應(yīng)用于工業(yè)控制領(lǐng)域,易控(INSPEC)是北京九思易自動化軟件有限公司(ControlEase AutomationSoftware)推出的一套通用數(shù)據(jù)采集和監(jiān)控(SCADA)軟件,具有最新的.NET Framework 框架平臺,應(yīng)用極為廣泛。為了與現(xiàn)場設(shè)備進行交互, INSPEC提供了國內(nèi)外各種常用的工控設(shè)備的驅(qū)動程序。但是由于現(xiàn)場設(shè)備種類繁多,支持的通信協(xié)議各不相同,因此,需要針對不同的底層設(shè)備編寫相應(yīng)的驅(qū)動程序,以實現(xiàn)同組態(tài)軟件的信息交互。許多底層設(shè)備采用單片機進行設(shè)計,本文針對基于51單片機的設(shè)備進行了通用的驅(qū)動程序設(shè)計,通過此通用驅(qū)動程序,設(shè)計者只需簡單的設(shè)置就可以將基于51單片機的儀表、設(shè)備接入INSPEC,無需重新開發(fā)驅(qū)動程序。而且只需將所設(shè)計的驅(qū)動程序進行少量改動,即可適應(yīng)各種類型的設(shè)備,或與其他類型的單片機進行通信。
1 基于51單片機的設(shè)備與上位組態(tài)軟件的連接
對于易控組態(tài)軟件,底層設(shè)備屬于I/O設(shè)備。上位機通過硬件通道與硬件設(shè)備建立連接關(guān)系,按照對應(yīng)的通信協(xié)議與硬件設(shè)備交換數(shù)據(jù),并將采集到的運行數(shù)據(jù)經(jīng)轉(zhuǎn)換后通過數(shù)據(jù)庫接口傳送至數(shù)據(jù)庫,同時響應(yīng)數(shù)據(jù)庫關(guān)聯(lián)變量來改變事件,將輸入數(shù)據(jù)寫入硬件設(shè)備。51單片機提供了一個全雙工標(biāo)準(zhǔn)接口,通過電平轉(zhuǎn)換芯片MAX232及相關(guān)外圍電路來實現(xiàn)TTL信號和RS-232電平信號之間的轉(zhuǎn)換,并實現(xiàn)與計算機串口RS-232的硬件通信通道連接。通過設(shè)備驅(qū)動程序,完成基于51單片機的設(shè)備與上位組態(tài)軟件的數(shù)據(jù)交互。其接口結(jié)構(gòu)如圖1所示。
2 利用開發(fā)向?qū)沈?qū)動程序的框架[1-2]
根據(jù)INSPEC組態(tài)軟件I/O系統(tǒng)的驅(qū)動設(shè)計規(guī)范, I/O系統(tǒng)由服務(wù)器類(DeviceIoMgr)、通道類(Channel)、設(shè)備類(Device)、I/O變量類(IoTag)構(gòu)成。INSPEC提供了設(shè)備驅(qū)動程序開發(fā)包(SDK),驅(qū)動程序的開發(fā)環(huán)境為Visual Studio 2008。采用C#為開發(fā)語言,易控提供驅(qū)動程序開發(fā)模板。
2.1 設(shè)備驅(qū)動程序的建立
設(shè)備驅(qū)動程序的建立需運行Microsoft Visual Studio 2008,新建項目類型為“Visual C# 易控(INSPEC)”,在“我的模板”位置會出現(xiàn)“設(shè)備通信”模板,輸入項目名稱為單片機通用驅(qū)動,支持通道名稱選擇串口,根據(jù)向?qū)瓿尚陆椖康呐渲?。然后修改項目的三個重要屬性:
(1) 程序集名稱要遵從“Controlease.IoDrive.廠家名.設(shè)備名”的規(guī)則。在項目屬性設(shè)置窗口中,點擊“應(yīng)用程序”, 將程序集名稱修改為ControlEase.IoDrive.Control
Ease.單片機通用驅(qū)動。
(2) 生成事件是生成I/O設(shè)備驅(qū)動的DLL文件。由于易控啟動時從文件夾..\ControlEase\INSPEC\Devices下加載驅(qū)動,所以將生成驅(qū)動DLL的路徑設(shè)置在此目錄。
(3) 引用路徑是驅(qū)動項目中引用類庫的路徑,一般設(shè)置在..\ControlEase\INSPEC\目錄下。
2.2 驅(qū)動程序的設(shè)計方法
在易控提供的驅(qū)動程序開發(fā)模板下,為了實現(xiàn)I/O設(shè)備的自定義功能,主要修改設(shè)備通信模板的讀、寫以及特殊操作方法。本通用驅(qū)動程序的設(shè)計修改了單片機通用驅(qū)動Protocol.cs類中的ReadPacket(SampleTagPacket packet)和WriteTag(IoTag tag)方法。
(1) 設(shè)備數(shù)據(jù)采集
易控采用循環(huán)采集的方式來采集現(xiàn)場設(shè)備數(shù)據(jù)。所有具有“只讀/讀寫”屬性的I/O量,都會按照I/O變量設(shè)置的“查詢周期”進行采集。每次采集過程都會進入ReadPacket方法中。
設(shè)備數(shù)據(jù)采集過程,默認(rèn)采集方式為變量包采集方式。在該設(shè)備通信程序開發(fā)包里,把所有在INSPEC軟件中添加的可讀IoTag都添加到了一個數(shù)據(jù)包中,采集程序從bool ReadPacket(SampleTagPacket packet)方法進入,數(shù)據(jù)采集流程圖如圖2所示。
數(shù)據(jù)采集部分編程如下:
public override bool ReadPacket(SampleTagPacket packet)
{
int sendCount = FormReadOrder(packet);
int toReceiveCount = packet.Length * 4 + 5;
if (packet.RegType == RegTypeList.CoilStatus.ToString()
|| packet.RegType == RegTypeList.InputStatus.ToString())
{
toReceiveCount = packet.Length % 8 == 0 ? (packet.
Length/8+5) : (packet.Length/8+1+5);
}
int receiveCount=WriteAndRead(sendCount, toReceive
Count);
if (receiveCount < toReceiveCount)
{
TraceLog.TraceError(string.Format(Resources.NOT_ENOUGH_
DATA_RECEIVED, receiveCount));
return false;
}
if (!CheckOutReceivedData(receiveCount))
{
return false;
}
return ParseIO(packet, receiveCount);
}
在這段代碼中,首先調(diào)用FormReadOrde方法,組成了通信協(xié)議幀,并返回讀命令長度。然后通過WriteAndRead方法,完成了串口的讀寫操作,即完成了上位機與設(shè)備間的一次通信。收到返回數(shù)據(jù)以后,調(diào)用CheckOutReceivedData方法,對從串口接收到的數(shù)據(jù)進行校驗。最后,調(diào)用數(shù)據(jù)解析ParseI/O方法,將接收到的數(shù)據(jù)轉(zhuǎn)換成I/O變量的值。
(2) 寫設(shè)備變量
易控中所有的賦值操作,只要I/O變量具有“只寫/讀寫”屬性,并且I/O變量關(guān)聯(lián)的數(shù)據(jù)庫變量的值發(fā)生變化,都會觸發(fā)寫操作,并進入WriteTag方法。將參數(shù)寫到設(shè)備里面,默認(rèn)調(diào)用方式為寫IoTag,程序從bool WriteTag(IoTag tag)方法進入,寫設(shè)備變量流程圖如圖3所示。
寫設(shè)備變量部分編程如下:
public override bool WriteTag(IoTag tag)
{
int sendCount = FillWriteFrame(tag);
if (sendCount <= 0)
{
return true;
}
const int toReceiveCount = 10;
int receiveCount = WriteAndRead(sendCount, toReceive-
Count);
if(!CheckOutReceivedData(receiveCount, toReceiveCount))
{
return false;
}
return true;
}
在這段代碼中,首先調(diào)用FormWriteOrder方法,組成了通信協(xié)議幀,并返回寫命令長度,然后通過WriteAndRead方法,完成了串口的讀寫操作,即上位機與設(shè)備完成了一次通信。在收到返回數(shù)據(jù)以后,調(diào)用CheckOutReceivedData方法,對串口接收到的數(shù)據(jù)進行校驗。
2.3 數(shù)據(jù)打包
易控進行設(shè)備數(shù)據(jù)采集的最小單位是一個數(shù)據(jù)包(SampleTagPacket)。在默認(rèn)設(shè)備采集過程中,所有的查詢周期相同的IoTag都將會打包到同一個數(shù)據(jù)包中。這個數(shù)據(jù)包就是易控的基本采集單位變量包packet,即IoTag的集合。設(shè)備類中的CanAddToPacket方法是為讀打包服務(wù)的,該方法將返回一個Bool值,用來判斷是否可以打成一個包。在該方法下設(shè)計需要打包寄存器的條件,只要返回TRUE,滿足條件的寄存器就會自動打成一個包。
CanAddToPacket有兩個參數(shù),packet指的就是包,它包括多個滿足打包條件的tag(tag指準(zhǔn)備要打包的寄存器)。如果滿足打包條件,tag就會被添加到packet中。具體實現(xiàn)方法如下:
Protected override bool CanAddToPacket(SampleTagPacket packet, IoTag tag)
{
if (packet.RegType != tag.RegType)
{
return false;
}
if(SerialDevice1BaseInfo.IsBitRegister(packet.RegType) &&Get-
CombineLength(packet,tag)>=SerialDevice1BaseInfo.MaxCombine
Length * 16)
{
return false;
}
if(GetCombineLength(packet,tag)>=SerialDevice1BaseInfo.
MaxCombineLength * 16)
{
return false;
}
return base.CanAddToPacket(packet, tag);
}
2.4 驅(qū)動程序通道配置
INSPEC在I/O通信的通道中配置復(fù)雜的串行端口參數(shù)(如波特率大小,數(shù)據(jù)位長度,停止位位數(shù),有無奇偶校驗等)、初始化和讀寫操作,用戶可以針對不同設(shè)備的通信協(xié)議進行相關(guān)的配置,即可將51單片機儀表和設(shè)備接入INSPEC,避免了驅(qū)動程序的重復(fù)開發(fā)。
通道配置完成后,點擊“下一步”進行設(shè)備的選擇,編寫好的設(shè)備驅(qū)動“單片機通用設(shè)備”已經(jīng)加載到了易控可選設(shè)備中,如圖4所示。由于易控中提供兩種數(shù)據(jù)傳遞類型,一種是比較常用的字節(jié)形式(ByteArrayParseInfo),另一種是在智能儀表中常用的ASCII碼字符串形式(StringParseInfo)。根據(jù)協(xié)議能很方便地確認(rèn)設(shè)備采用的是哪一種形式,然后根據(jù)需要定義對應(yīng)的數(shù)據(jù)轉(zhuǎn)換信息類,這里選擇的是字符串方式。點擊“完成”即建好通道。
3 基于51單片機的通信程序設(shè)計[3]
該驅(qū)動程序具有較強的通用性,在INSPEC中用戶只需根據(jù)底層設(shè)備的通信協(xié)議進行通道配置即能完成INSPEC與下位機之間的通信;另一方面,用戶也可以先配置好INSPEC的通道,并根據(jù)通道配置在下位51單片機的通信程序里進行相關(guān)協(xié)議的編寫,實現(xiàn)上位和下位機的通信協(xié)議的一致性。
51單片機的串行口內(nèi)部有兩個物理上獨立的接收、發(fā)送緩沖器SBUF,可同時發(fā)送、接收數(shù)據(jù)。用戶將數(shù)據(jù)存放在SBUF寄存器里來完成與上位機INSPEC的數(shù)據(jù)交互。為了更好地體現(xiàn)驅(qū)動程序的通用性,在驅(qū)動程序里定義了收發(fā)數(shù)據(jù)的緩沖區(qū)大小,用戶只需將底層設(shè)備的數(shù)據(jù)存儲到已定義的緩沖區(qū)里就能完成數(shù)據(jù)的交互,編程如下:
private readonly byte[] mReceiveBuffer = new byte[2048] //用于保存接收到的數(shù)據(jù)
private readonly byte[] mSendBuffer = new byte[1024]
//用于保存發(fā)送的命令
這里單片機串口工作于方式1,數(shù)據(jù)幀格式為8 bit數(shù)據(jù)位,1 bit停止位,定時/計數(shù)器1用作波特率發(fā)生器,PCON中的SMOD位為0,發(fā)送的波特率為9 600,系統(tǒng)初始化程序如下:
TMOD=0x22; //定時器T1,在方式2中斷產(chǎn)生
//波特率
PCON &=0x00; //波特率不倍增,SMOD=0
SCON=0x40;
TH1=0xfd; //波特率設(shè)置為9 600
TL1=0xfd;
4 通用驅(qū)動程序在電壓監(jiān)測儀表上的應(yīng)用
該應(yīng)用中下位機采用STC89C52系列單片機為主控芯片的電壓監(jiān)測儀表,上位機監(jiān)控軟件為INSPEC。由于已經(jīng)編寫了單片機的通信協(xié)議,所以在易控中進行通道配置時應(yīng)該與單片機通信協(xié)議保持一致,即8 bit數(shù)據(jù)位,1 bit停止位,波特率為9 600。通道配置完成后,在設(shè)備中選擇單片機通用驅(qū)動就完成了I/O通信的配置。
電壓監(jiān)測儀表中的電壓傳感器將采集的電壓信號傳給A/D模塊進行數(shù)據(jù)轉(zhuǎn)換,并進入單片機進行數(shù)據(jù)處理,經(jīng)RS-232端口與上位機的監(jiān)控軟件INSPEC通信。通過數(shù)據(jù)交互,可在上位機上直接顯示現(xiàn)場的電壓值,以達到對現(xiàn)場電壓的實時監(jiān)測。
4.1 上位機監(jiān)控界面的設(shè)計[4]
INSPEC軟件能夠很方便地實現(xiàn)對自動化過程和裝備的監(jiān)測和控制。在INSPEC中添加實時數(shù)據(jù)庫變量,其中包括了控制系統(tǒng)所需的數(shù)據(jù)交互信息:電壓設(shè)定值、監(jiān)測電壓值、電壓報警指示和監(jiān)測電壓的實時曲線圖等變量,使監(jiān)控窗口和數(shù)據(jù)通道的變量關(guān)聯(lián)起來。
4.2 驅(qū)動程序的裝載
在Microsoft Visual Studio 2008開發(fā)環(huán)境中,驅(qū)動程序編譯后在文件夾..\ControlEase\INSPEC\Devices下生成ControlEase.IoDrive.ControlEase.,單片機通用驅(qū)動.dll驅(qū)動文件。啟動易控開發(fā)環(huán)境時,會自動將驅(qū)動文件加載到易控的設(shè)備選擇中供用戶選擇。
針對組態(tài)軟件應(yīng)用中驅(qū)動程序的開發(fā)問題,本文設(shè)計了基于INSPEC的51系列單片機通用驅(qū)動程序。實現(xiàn)了INSPEC和單片機控制的外部設(shè)備進行通信,解決了基于51系列單片機設(shè)備驅(qū)動程序的重復(fù)設(shè)計問題。為以后開發(fā)其他設(shè)備驅(qū)動程序提供了設(shè)計思路和程序框架,對實現(xiàn)底層設(shè)備方便接入組態(tài)軟件進行了有益的探索。
參考文獻
[1] 北京九思易自動化軟件有限公司.易控(INSPEC)高級開發(fā)指南[M]. 2009.
[2] ROBINSON S, CORNES O. C#高級編程[M]. 康博,譯. 北京:清華大學(xué)出版社,2002.
[3] 李全利,遲榮強.單片機原理及接口技術(shù)[M].北京:高等教育出版社,2004.
[4] 北京九思易自動化軟件有限公司.易控(INSPEC)培訓(xùn)教程[M]. 2009.