《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計應(yīng)用 > 基于易控的51系列單片機通用驅(qū)動程序設(shè)計
基于易控的51系列單片機通用驅(qū)動程序設(shè)計
來源:電子技術(shù)應(yīng)用2011年第11期
李建平, 鄭 萍, 葉建平, 陶 平, 溫百東, 朱光燦
(西華大學(xué) 電氣信息學(xué)院, 四川 成都610039)
摘要: 設(shè)計了一種基于易控(INSPEC)組態(tài)軟件的51單片機外部設(shè)備的通用驅(qū)動程序,以解決基于51單片機的底層設(shè)備驅(qū)動問題。該通用驅(qū)動程序通過電壓監(jiān)測儀表進行了應(yīng)用調(diào)試,證明了該驅(qū)動程序?qū)嵱靡仔校槠渌脑O(shè)備驅(qū)動程序設(shè)計提供了設(shè)計思路和程序框架。
中圖分類號: TP273
文獻標(biāo)識碼: A
文章編號: 0258-7998(2011)11-0144-03
Design of general driver for the 51 series MCU based on the INSPEC
Li Jianping, Zheng Ping, Ye Jianping, Tao Ping, Wen Baidong, Zhu Guangcan
School of Electrical and Information Engineering, Xihua University, Chengdu 610039, China
Abstract: A general device driver was designed based on the INSPEC which extremely widespread application of 51 series MCU, in order to solve the underlying driver problems of 51 series MCU . The driver was debugged by using the infrared Remote voltage monitoring instrument. The result proved that the driver is practical and feasible, and has provided the design ideas and the program frame for the design of general device driver.
Key words : data communication; INSPEC; configuration software;MCU; driver


    目前,工業(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變量具有&ldquo;只寫/讀寫&rdquo;屬性,并且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ā)。
    通道配置完成后,點擊&ldquo;下一步&rdquo;進行設(shè)備的選擇,編寫好的設(shè)備驅(qū)動&ldquo;單片機通用設(shè)備&rdquo;已經(jīng)加載到了易控可選設(shè)備中,如圖4所示。由于易控中提供兩種數(shù)據(jù)傳遞類型,一種是比較常用的字節(jié)形式(ByteArrayParseInfo),另一種是在智能儀表中常用的ASCII碼字符串形式(StringParseInfo)。根據(jù)協(xié)議能很方便地確認(rèn)設(shè)備采用的是哪一種形式,然后根據(jù)需要定義對應(yīng)的數(shù)據(jù)轉(zhuǎn)換信息類,這里選擇的是字符串方式。點擊&ldquo;完成&rdquo;即建好通道。

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.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。