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