(西南科技大學 信息學院特殊環境機器人技術四川省重點實驗室,綿陽 621010)
隨著傳統PLC在工業生產中的廣泛應用,逐漸表現出一些弊端:例如,不同品牌、不同型號的產品不能夠相互兼容;數據結構封閉,用戶不能添加或改變其功能;各廠家編程語言各不相同,使用人員需要經過長期專業化學習。以上問題制約著傳統PLC的發展,但隨著電子技術和計算機的發展以及IEC61131-3標準的制定和實施,涌現出了一種基于計算機來實現傳統PLC功能的軟PLC技術。相對傳統PLC,軟PLC具有開放的體系結構、強大數據分析和數據處理能力、友好人機界面及便于操作等優點[1]。
本系統采用C++語言開發,同時遵循可編程控制器標準IEC61131-3。系統采用模塊化的設計方法,將常用的程序功能分解為若干小模塊,并對每個小模塊加以封裝;支持自頂向下和自底向上兩種開發方式;該標準所規范的編程系統獨立于具體的目標系統,可以最大限度實現在不同的PLC目標系統中運行;提供多種編程語言,包括三種圖形化語言和兩種文本化語言,給程序編制人員提供更多的選擇[2]。
開發系統主要由編輯模塊、項目管理模塊、仿真模塊、通信模塊和編譯模塊組成。編輯模塊即梯形圖編輯器,主要功能包括梯形圖圖元的繪制、編輯、保存和讀取以及注解、邏輯檢查;編譯模塊進行梯形圖到指令表的轉換以及由指令表編譯生成目標代碼;仿真模塊進行元件的測試、跟蹤調試、狀態監控;通信模塊作為開發系統和運行系統的連接樞紐,實現它們之間信息交換[3]。軟PLC開發系統模塊如圖1所示。

圖1 軟PLC開發系統模塊
編輯界面是系統與用戶交互的窗口,不但可以編寫程序,而且還可以利用該界面將編寫好的程序送到存儲區,同時可以進行檢查、調試和修改程序,監控程序的運行情況,通過外圍硬件調入及顯示保護裝置的狀態、系統參數,通過接口與CPU聯系,實現人機對話。
本開發系統的梯形圖編輯界面利用VC++中MFC的文檔/視圖結構來設計,該結構中的文檔負責數據的維護和管理,視圖用來顯示。該編輯界面不但具有標準Windows環境下的標題欄、工具欄、菜單欄、狀態欄,而且具有針對編程環境所設計的梯形圖繪制區和梯形圖元件工具箱。梯形圖繪制區域左邊框輸出為左母線,右邊框輸出為右母線,畫布被劃分成9行、16列,用黑色小點進行劃分。用戶可以根據程序大小,設置畫布的大小,本編輯界面最大支持100行、16列。梯形圖編輯界面如圖2所示。

圖2 梯形圖的編輯界面
梯形圖的圖元由可編輯屬性的圖形符號構成,是輸入、輸出繼電器等器件的抽象表示形式。隨著PLC控制對象的復雜化,控制功能的具體化,梯形圖的圖元種類越來越多。因此,需要考慮如何應對梯形圖的圖元種類繁多這個問題。通過分析發現,可以把圖元劃分成不同種類,通過提取共同特征,利用C++語言的封裝性、繼承性和多態性,構建一個圖元的基類,通過類的繼承和擴展派生出具有不同特性的指令圖元[4]。圖元由結構定義、繪制生成方法和基本屬性三部分構成。圖元結構定義為:

繪制某個圖元時,用戶首先用鼠標選中要繪制的元件,然后在編輯區選中元件放置的位置,最后單擊鼠標的左鍵就可以完成繪制。其中具體的繪制流程如圖3所示。

圖3 圖元繪制過程
不同的圖元具有一些相同屬性或功能,例如圖元的類型、大小、名稱、使用說明,此外還有復制功能、顯示功能、保存及參數設置等功能。因此定義圖元屬性結構基本上包括位置信息、接口信息、連接信息。圖元的位置信息規定圖元在編輯界面中的位置參數。接口信息規定圖元的線性、線寬、顏色、文本輸入等[5]。連接屬性描述各圖元元件屬性與接口數據及表達式的對應關系,建立連接后可以進行數據參數傳遞,從而實現圖元屬性和外觀的改變。
梯形圖是由圖元按一定規則組合而成,圖元之間不但存在位置關系還存在邏輯關系,如何正確描述并保存圖元之間的位置和邏輯關系是梯形圖編輯模塊中要的一個重要環節。通過分析發現,梯形圖程序是由若干網絡構成,網絡由若干行構成,行由若干圖元組成。梯形圖編輯是一個動態的過程,網絡、行數和圖元均不確定,因此梯形圖的存儲需要動態分配存儲空間。根據該特點考慮采用鏈表存儲結構。除此之外,梯形圖編輯過程常常進行刪除、插入、剪切、復制等操作,這些操作使用指針可以方便地完成。雙向鏈表是環形結構,可以從任意結點遍歷整個鏈表。在雙向鏈表中,每個結點包括三個域,分別是data(數據域)、next(后繼結點指針)和prior(前繼結點指針)。雙向鏈表結點的結構如圖4所示。采用行雙向鏈表對梯形圖每行進行存儲,head指針是頭指針,current指針為當前指針,tail指針為尾指針,其結構如圖5所示。

圖4 雙向鏈表結點的圖示結構

圖5 行雙向鏈數據結構圖
由于梯形圖具有形象直觀和易于編程的特點成為PLC最常用編程語言之一,但卻不能被PLC的CPU直接識別。指令表類似匯編語言,便于底層運行系統解釋執行。因此,為了使梯形圖被PLC的CPU識別,可將梯形圖轉換成指令表。有多種方法將梯形圖轉換為指令表,本文采用AOV有向圖和串并聯掃描的方法,該方法相對其他方法具有效率高、占用空間少、邏輯錯誤查找快等優點。該方法是梯形圖映射成為AOV有向圖,從而確定各元件后繼和前驅關系,再利用串并聯掃描構建邏輯樹,確定元件之間的邏輯關系,最后對邏輯樹進行遍歷,生成指令表。
AOV圖由頂點和弧構成,梯形圖則由若干圖元和線段按照一定規則相互連接而成。通過分析發現,可以把梯形圖中的圖元看作AOV圖的頂點,圖元之間的連線看作弧,因此就可以實現梯形圖到AOV的映射[6]。同時,映射需要在母線和其它聯結處加入虛頂點。下面給出一個梯形圖實例和對應映射的AOV有向圖,分別如圖6和如圖7所示,其中AOV有向圖中頂點1、2是兩個虛頂點。

圖6 梯形圖
雖然AOV能描述出各元件的后繼和前驅的關系,但是不能描述其邏輯關系即串并聯關系,因此需要進一步研究圖元的串并聯關系[7]。基于AOV有向圖的串并聯掃描的步驟如下:

圖7 AOV有向圖
1)對AOV進行掃描,確定串聯或并聯關系;2)對更新AOV圖進行串并聯掃描,同樣根據掃描結果去更新AOV圖;3)重復執行1)和2),直到能夠生成能夠清楚反應邏輯關系邏輯樹。
以圖7的AOV有向圖為例,I0.0和I0.1是串聯關系,可以用串1表示;I0.2和I0.3是串聯可以用串2表示;I0.5和I0.6串聯用串3表示;串1、串3、I1.1并聯可以用并1表示。如此不斷掃描更新,最終建立一棵完整的邏輯樹如圖8所示。對邏輯樹進行后序遍歷生成指令表如表1所示。

圖8 串并聯掃描生產的邏輯樹

表1 遍歷生成的指令表
指令表雖然是類似匯編的底層語言,但是它編寫的程序卻不能被PLC的CPU直接識別和執行。指令表程序在PLC運行之前,需要翻譯成CPU能夠識別的二進制代碼[8]。指令表程序翻譯成目標機器可以執行的機器碼,需要經過四個階段:詞法分析階段、語法分析階段、詞義分析及代碼優化階段、目標代碼生成階段。編譯過程如圖7所示。

圖9 指令表編譯過程
本文采用Flex工具和Bison工具進行詞法語法分析。Flex是一種詞法分析程序生成軟件,會根據規則生成一個Flex文件,該文件由定義段、規則段和用戶代碼段組成。其結構的格式如下:<定義段>、<語法規則段>和<用戶子程序段>。定義段包括詞法分析選項、外部變量、宏及函數聲明、結構定義、開始狀態聲明,名字定義等。規則段以“%%”開始和結束的,是Flex輸入文件的主干,并且和后面的語法分析密切相關。規則段由模式和動作組成,模式是匹配單詞的正則表達,動作是掃描指令表源文并識別出一個單詞時,詞法分析程序采取相應的行為。
Bison是一種通用目的的語法分析程序生成器,它使用自下而上的向前LALR分析方法造語法樹,將LALR(1)上下文無關文法的描述轉化成分析文法的C程序[9]。Bison的語法規則形式由終結符和非終結符組合表示。Bison源程序結構由<聲明段>、<語法規則段>和<用戶子程序段>三部分組成。聲明段是以“%{”符號開始,以“%}”符號結束,定義類型和變量、宏等頭文件以及聲明全局標識符和一些函數。語法規則段是由一條或多條規則組成,每條規則以分號結束。用戶子程序段包含必須的頭文件,定義聲明函數和其它輔助函數。
梯形圖的編輯需要符合編程規則和邏輯規則,當發現梯形圖存在邏輯錯誤,軟件以框圖的形式向用戶報錯并且向用戶指出錯誤的位置和類型[10]。針對常見邏輯錯誤進行如下的分類:左右母線直接水平相連,中間沒有元器件;輸入線圈與左母線直接相連;輸出線圈后面有圖元連接;出現斷路、短路的情況;同一地址輸出線圈多次使用造成邏輯混亂;出現線圈串聯;功能塊指令缺少輸入和輸出[11]。
本文闡述了利用c++語言開發軟PLC技術的實現方法,該方法能夠實現PLC梯形圖的繪制、邏輯檢錯、存儲以及梯形圖到指令表的轉換,通過對指令表的編譯生成運行系統可執行的目標代碼。本方法采用面向對象編程技術,使得系統具有易維護、易擴展、效率高的優點。