(西南科技大學(xué) 信息學(xué)院特殊環(huán)境機器人技術(shù)四川省重點實驗室,綿陽 621010)
隨著傳統(tǒng)PLC在工業(yè)生產(chǎn)中的廣泛應(yīng)用,逐漸表現(xiàn)出一些弊端:例如,不同品牌、不同型號的產(chǎn)品不能夠相互兼容;數(shù)據(jù)結(jié)構(gòu)封閉,用戶不能添加或改變其功能;各廠家編程語言各不相同,使用人員需要經(jīng)過長期專業(yè)化學(xué)習(xí)。以上問題制約著傳統(tǒng)PLC的發(fā)展,但隨著電子技術(shù)和計算機的發(fā)展以及IEC61131-3標準的制定和實施,涌現(xiàn)出了一種基于計算機來實現(xiàn)傳統(tǒng)PLC功能的軟PLC技術(shù)。相對傳統(tǒng)PLC,軟PLC具有開放的體系結(jié)構(gòu)、強大數(shù)據(jù)分析和數(shù)據(jù)處理能力、友好人機界面及便于操作等優(yōu)點[1]。
本系統(tǒng)采用C++語言開發(fā),同時遵循可編程控制器標準IEC61131-3。系統(tǒng)采用模塊化的設(shè)計方法,將常用的程序功能分解為若干小模塊,并對每個小模塊加以封裝;支持自頂向下和自底向上兩種開發(fā)方式;該標準所規(guī)范的編程系統(tǒng)獨立于具體的目標系統(tǒng),可以最大限度實現(xiàn)在不同的PLC目標系統(tǒng)中運行;提供多種編程語言,包括三種圖形化語言和兩種文本化語言,給程序編制人員提供更多的選擇[2]。
開發(fā)系統(tǒng)主要由編輯模塊、項目管理模塊、仿真模塊、通信模塊和編譯模塊組成。編輯模塊即梯形圖編輯器,主要功能包括梯形圖圖元的繪制、編輯、保存和讀取以及注解、邏輯檢查;編譯模塊進行梯形圖到指令表的轉(zhuǎn)換以及由指令表編譯生成目標代碼;仿真模塊進行元件的測試、跟蹤調(diào)試、狀態(tài)監(jiān)控;通信模塊作為開發(fā)系統(tǒng)和運行系統(tǒng)的連接樞紐,實現(xiàn)它們之間信息交換[3]。軟PLC開發(fā)系統(tǒng)模塊如圖1所示。
圖1 軟PLC開發(fā)系統(tǒng)模塊
編輯界面是系統(tǒng)與用戶交互的窗口,不但可以編寫程序,而且還可以利用該界面將編寫好的程序送到存儲區(qū),同時可以進行檢查、調(diào)試和修改程序,監(jiān)控程序的運行情況,通過外圍硬件調(diào)入及顯示保護裝置的狀態(tài)、系統(tǒng)參數(shù),通過接口與CPU聯(lián)系,實現(xiàn)人機對話。
本開發(fā)系統(tǒng)的梯形圖編輯界面利用VC++中MFC的文檔/視圖結(jié)構(gòu)來設(shè)計,該結(jié)構(gòu)中的文檔負責(zé)數(shù)據(jù)的維護和管理,視圖用來顯示。該編輯界面不但具有標準Windows環(huán)境下的標題欄、工具欄、菜單欄、狀態(tài)欄,而且具有針對編程環(huán)境所設(shè)計的梯形圖繪制區(qū)和梯形圖元件工具箱。梯形圖繪制區(qū)域左邊框輸出為左母線,右邊框輸出為右母線,畫布被劃分成9行、16列,用黑色小點進行劃分。用戶可以根據(jù)程序大小,設(shè)置畫布的大小,本編輯界面最大支持100行、16列。梯形圖編輯界面如圖2所示。
圖2 梯形圖的編輯界面
梯形圖的圖元由可編輯屬性的圖形符號構(gòu)成,是輸入、輸出繼電器等器件的抽象表示形式。隨著PLC控制對象的復(fù)雜化,控制功能的具體化,梯形圖的圖元種類越來越多。因此,需要考慮如何應(yīng)對梯形圖的圖元種類繁多這個問題。通過分析發(fā)現(xiàn),可以把圖元劃分成不同種類,通過提取共同特征,利用C++語言的封裝性、繼承性和多態(tài)性,構(gòu)建一個圖元的基類,通過類的繼承和擴展派生出具有不同特性的指令圖元[4]。圖元由結(jié)構(gòu)定義、繪制生成方法和基本屬性三部分構(gòu)成。圖元結(jié)構(gòu)定義為:
繪制某個圖元時,用戶首先用鼠標選中要繪制的元件,然后在編輯區(qū)選中元件放置的位置,最后單擊鼠標的左鍵就可以完成繪制。其中具體的繪制流程如圖3所示。
圖3 圖元繪制過程
不同的圖元具有一些相同屬性或功能,例如圖元的類型、大小、名稱、使用說明,此外還有復(fù)制功能、顯示功能、保存及參數(shù)設(shè)置等功能。因此定義圖元屬性結(jié)構(gòu)基本上包括位置信息、接口信息、連接信息。圖元的位置信息規(guī)定圖元在編輯界面中的位置參數(shù)。接口信息規(guī)定圖元的線性、線寬、顏色、文本輸入等[5]。連接屬性描述各圖元元件屬性與接口數(shù)據(jù)及表達式的對應(yīng)關(guān)系,建立連接后可以進行數(shù)據(jù)參數(shù)傳遞,從而實現(xiàn)圖元屬性和外觀的改變。
梯形圖是由圖元按一定規(guī)則組合而成,圖元之間不但存在位置關(guān)系還存在邏輯關(guān)系,如何正確描述并保存圖元之間的位置和邏輯關(guān)系是梯形圖編輯模塊中要的一個重要環(huán)節(jié)。通過分析發(fā)現(xiàn),梯形圖程序是由若干網(wǎng)絡(luò)構(gòu)成,網(wǎng)絡(luò)由若干行構(gòu)成,行由若干圖元組成。梯形圖編輯是一個動態(tài)的過程,網(wǎng)絡(luò)、行數(shù)和圖元均不確定,因此梯形圖的存儲需要動態(tài)分配存儲空間。根據(jù)該特點考慮采用鏈表存儲結(jié)構(gòu)。除此之外,梯形圖編輯過程常常進行刪除、插入、剪切、復(fù)制等操作,這些操作使用指針可以方便地完成。雙向鏈表是環(huán)形結(jié)構(gòu),可以從任意結(jié)點遍歷整個鏈表。在雙向鏈表中,每個結(jié)點包括三個域,分別是data(數(shù)據(jù)域)、next(后繼結(jié)點指針)和prior(前繼結(jié)點指針)。雙向鏈表結(jié)點的結(jié)構(gòu)如圖4所示。采用行雙向鏈表對梯形圖每行進行存儲,head指針是頭指針,current指針為當前指針,tail指針為尾指針,其結(jié)構(gòu)如圖5所示。
圖4 雙向鏈表結(jié)點的圖示結(jié)構(gòu)
圖5 行雙向鏈數(shù)據(jù)結(jié)構(gòu)圖
由于梯形圖具有形象直觀和易于編程的特點成為PLC最常用編程語言之一,但卻不能被PLC的CPU直接識別。指令表類似匯編語言,便于底層運行系統(tǒng)解釋執(zhí)行。因此,為了使梯形圖被PLC的CPU識別,可將梯形圖轉(zhuǎn)換成指令表。有多種方法將梯形圖轉(zhuǎn)換為指令表,本文采用AOV有向圖和串并聯(lián)掃描的方法,該方法相對其他方法具有效率高、占用空間少、邏輯錯誤查找快等優(yōu)點。該方法是梯形圖映射成為AOV有向圖,從而確定各元件后繼和前驅(qū)關(guān)系,再利用串并聯(lián)掃描構(gòu)建邏輯樹,確定元件之間的邏輯關(guān)系,最后對邏輯樹進行遍歷,生成指令表。
AOV圖由頂點和弧構(gòu)成,梯形圖則由若干圖元和線段按照一定規(guī)則相互連接而成。通過分析發(fā)現(xiàn),可以把梯形圖中的圖元看作AOV圖的頂點,圖元之間的連線看作弧,因此就可以實現(xiàn)梯形圖到AOV的映射[6]。同時,映射需要在母線和其它聯(lián)結(jié)處加入虛頂點。下面給出一個梯形圖實例和對應(yīng)映射的AOV有向圖,分別如圖6和如圖7所示,其中AOV有向圖中頂點1、2是兩個虛頂點。
圖6 梯形圖
雖然AOV能描述出各元件的后繼和前驅(qū)的關(guān)系,但是不能描述其邏輯關(guān)系即串并聯(lián)關(guān)系,因此需要進一步研究圖元的串并聯(lián)關(guān)系[7]?;贏OV有向圖的串并聯(lián)掃描的步驟如下:
圖7 AOV有向圖
1)對AOV進行掃描,確定串聯(lián)或并聯(lián)關(guān)系;2)對更新AOV圖進行串并聯(lián)掃描,同樣根據(jù)掃描結(jié)果去更新AOV圖;3)重復(fù)執(zhí)行1)和2),直到能夠生成能夠清楚反應(yīng)邏輯關(guān)系邏輯樹。
以圖7的AOV有向圖為例,I0.0和I0.1是串聯(lián)關(guān)系,可以用串1表示;I0.2和I0.3是串聯(lián)可以用串2表示;I0.5和I0.6串聯(lián)用串3表示;串1、串3、I1.1并聯(lián)可以用并1表示。如此不斷掃描更新,最終建立一棵完整的邏輯樹如圖8所示。對邏輯樹進行后序遍歷生成指令表如表1所示。
圖8 串并聯(lián)掃描生產(chǎn)的邏輯樹
表1 遍歷生成的指令表
指令表雖然是類似匯編的底層語言,但是它編寫的程序卻不能被PLC的CPU直接識別和執(zhí)行。指令表程序在PLC運行之前,需要翻譯成CPU能夠識別的二進制代碼[8]。指令表程序翻譯成目標機器可以執(zhí)行的機器碼,需要經(jīng)過四個階段:詞法分析階段、語法分析階段、詞義分析及代碼優(yōu)化階段、目標代碼生成階段。編譯過程如圖7所示。
圖9 指令表編譯過程
本文采用Flex工具和Bison工具進行詞法語法分析。Flex是一種詞法分析程序生成軟件,會根據(jù)規(guī)則生成一個Flex文件,該文件由定義段、規(guī)則段和用戶代碼段組成。其結(jié)構(gòu)的格式如下:<定義段>、<語法規(guī)則段>和<用戶子程序段>。定義段包括詞法分析選項、外部變量、宏及函數(shù)聲明、結(jié)構(gòu)定義、開始狀態(tài)聲明,名字定義等。規(guī)則段以“%%”開始和結(jié)束的,是Flex輸入文件的主干,并且和后面的語法分析密切相關(guān)。規(guī)則段由模式和動作組成,模式是匹配單詞的正則表達,動作是掃描指令表源文并識別出一個單詞時,詞法分析程序采取相應(yīng)的行為。
Bison是一種通用目的的語法分析程序生成器,它使用自下而上的向前LALR分析方法造語法樹,將LALR(1)上下文無關(guān)文法的描述轉(zhuǎn)化成分析文法的C程序[9]。Bison的語法規(guī)則形式由終結(jié)符和非終結(jié)符組合表示。Bison源程序結(jié)構(gòu)由<聲明段>、<語法規(guī)則段>和<用戶子程序段>三部分組成。聲明段是以“%{”符號開始,以“%}”符號結(jié)束,定義類型和變量、宏等頭文件以及聲明全局標識符和一些函數(shù)。語法規(guī)則段是由一條或多條規(guī)則組成,每條規(guī)則以分號結(jié)束。用戶子程序段包含必須的頭文件,定義聲明函數(shù)和其它輔助函數(shù)。
梯形圖的編輯需要符合編程規(guī)則和邏輯規(guī)則,當發(fā)現(xiàn)梯形圖存在邏輯錯誤,軟件以框圖的形式向用戶報錯并且向用戶指出錯誤的位置和類型[10]。針對常見邏輯錯誤進行如下的分類:左右母線直接水平相連,中間沒有元器件;輸入線圈與左母線直接相連;輸出線圈后面有圖元連接;出現(xiàn)斷路、短路的情況;同一地址輸出線圈多次使用造成邏輯混亂;出現(xiàn)線圈串聯(lián);功能塊指令缺少輸入和輸出[11]。
本文闡述了利用c++語言開發(fā)軟PLC技術(shù)的實現(xiàn)方法,該方法能夠?qū)崿F(xiàn)PLC梯形圖的繪制、邏輯檢錯、存儲以及梯形圖到指令表的轉(zhuǎn)換,通過對指令表的編譯生成運行系統(tǒng)可執(zhí)行的目標代碼。本方法采用面向?qū)ο缶幊碳夹g(shù),使得系統(tǒng)具有易維護、易擴展、效率高的優(yōu)點。