本發(fā)明涉及軟plc領(lǐng)域,尤其涉及一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法。
背景技術(shù):
20世紀(jì)90年代后期,傳統(tǒng)plc難以構(gòu)建開放的硬件體系結(jié)構(gòu)、工作人員必須經(jīng)過(guò)較長(zhǎng)時(shí)間的專業(yè)培訓(xùn)才能掌握某一種產(chǎn)品的編程方法、傳統(tǒng)plc的生產(chǎn)被幾家廠商所壟斷等缺點(diǎn)已經(jīng)嚴(yán)重制約了其發(fā)展。近年來(lái),隨著計(jì)算機(jī)技術(shù)的迅猛發(fā)展以及iec61131國(guó)際標(biāo)準(zhǔn)的指定,軟plc技術(shù)得到迅速發(fā)展。軟plc系統(tǒng)基于pc機(jī),建立在一定操作平臺(tái)之上,通過(guò)軟件的方法實(shí)現(xiàn)傳統(tǒng)plc的計(jì)算、控制、存儲(chǔ)和編程功能。
梯形圖和指令表都是可編程邏輯控制器的常用編程語(yǔ)言,它們都符合iec61131-3標(biāo)準(zhǔn)。梯形圖與電器控制系統(tǒng)的電路圖很相似,它是在常用的繼電器與接觸器邏輯控制基礎(chǔ)上簡(jiǎn)化了符號(hào)演變過(guò)來(lái),具有直觀易懂的優(yōu)點(diǎn),很容易被工廠電氣人員掌握,特別適合用于開關(guān)量的邏輯控制。在梯形圖中,左、右母線類似于繼電器與接觸器控制電源線,輸出線圈類似于負(fù)載,輸入觸點(diǎn)類似于按鈕。梯形圖由若干階級(jí)構(gòu)成,自上而下排列,每個(gè)階級(jí)起于左母線,經(jīng)過(guò)觸點(diǎn)與線圈,止于右母線。指令表編程語(yǔ)言是一種與匯編語(yǔ)言相類似的助記符編程語(yǔ)言,和匯編語(yǔ)言一樣由操作碼和操作數(shù)組成。指令表編程語(yǔ)言采用助記符來(lái)表示操作功能,具有容易記憶、便于掌握等特。與梯形圖相比,指令表更接近于機(jī)器語(yǔ)言,更容易被軟plc系統(tǒng)所識(shí)別。因此,設(shè)計(jì)一個(gè)方法將圖形化的梯形圖轉(zhuǎn)換成指令表是一個(gè)重要問(wèn)題。
目前,梯形圖向指令表轉(zhuǎn)換的方法主要有分成兩類:一類方法是直接對(duì)梯形圖進(jìn)行遍歷掃描,并在從上到下、從左到右掃描梯形圖時(shí),若遇到并聯(lián)支路,就轉(zhuǎn)入與當(dāng)前分支相鄰的下一行開始掃描,重復(fù)地使用這種策略從而得到指令表。另一種方法是使用二叉有向圖表示梯形圖的邏輯關(guān)系,并用二叉樹存儲(chǔ)梯形圖,通過(guò)對(duì)二叉樹的一次遍歷即可生成指令表。
技術(shù)實(shí)現(xiàn)要素:
為了克服現(xiàn)有技術(shù)存在的缺點(diǎn)與不足,本發(fā)明提供一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法,有效地解決梯形圖的復(fù)雜串并聯(lián)關(guān)系和多輸出難以準(zhǔn)確轉(zhuǎn)化成指令表的問(wèn)題;同時(shí)本發(fā)明能把轉(zhuǎn)化后的指令表解釋執(zhí)行,能結(jié)合emc數(shù)控系統(tǒng)構(gòu)成一套軟plc系統(tǒng)。
為解決上述技術(shù)問(wèn)題,本發(fā)明提供如下技術(shù)方案:一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法,包括如下步驟:
s1、遍歷梯形圖并構(gòu)造十字鏈表的所有頂點(diǎn),根據(jù)各頂點(diǎn)的邏輯關(guān)系構(gòu)造十字鏈表的弧鏈表,通過(guò)所有頂點(diǎn)和弧鏈表得到十字鏈表;
s2、利用串并聯(lián)歸并,化簡(jiǎn)十字鏈表得到包含指令間邏輯關(guān)系的二叉樹結(jié)構(gòu);
s3、遍歷二叉樹結(jié)構(gòu)得到對(duì)應(yīng)的指令表;
s4、利用堆棧的先進(jìn)先出原理解釋指令表。
進(jìn)一步地,所述步驟s1,具體為:
s11、構(gòu)造strrung結(jié)構(gòu)體保存梯形圖一行的信息,其中包括element數(shù)組,該數(shù)組的元素是保存梯形圖元件信息的strelement結(jié)構(gòu)體指針,然后用rung指針數(shù)組保存每一行的strrung結(jié)構(gòu)體指針;
s12、把除導(dǎo)線以外的其他元件看成有向圖的一個(gè)頂點(diǎn),構(gòu)造頂點(diǎn)結(jié)構(gòu)strvexnode并遍歷rung指針數(shù)組建立所有頂點(diǎn),頂點(diǎn)結(jié)構(gòu)包括一個(gè)指向二叉樹節(jié)點(diǎn)結(jié)構(gòu)strbinode指針;
s13、構(gòu)造弧節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)并且根據(jù)各頂點(diǎn)的邏輯關(guān)系構(gòu)造弧鏈表;
s14、通過(guò)所有頂點(diǎn)和弧鏈表得到十字鏈表。
進(jìn)一步地,所述步驟s2,具體為:
s21、利用串聯(lián)歸并,求入度為1的頂點(diǎn),由該頂點(diǎn)結(jié)構(gòu)的firstin域得到以該頂點(diǎn)為弧頭的第一個(gè)弧結(jié)點(diǎn),由弧結(jié)點(diǎn)得到弧尾頂點(diǎn),接著計(jì)算該弧尾頂點(diǎn)的出度和入度,如果弧尾頂點(diǎn)的出度為1且入度小于等于1,則弧尾和弧頭頂點(diǎn)合并為一個(gè)頂點(diǎn);合并時(shí)新建一個(gè)二叉樹節(jié)點(diǎn)binode,把弧尾頂點(diǎn)所包含的二叉樹節(jié)點(diǎn)指針賦值為binode的左子節(jié)點(diǎn),把弧頭頂點(diǎn)所包含的二叉樹節(jié)點(diǎn)指針賦值為binode的右子節(jié)點(diǎn),同時(shí)把binode的operator字段賦值為枚舉元素and,然后binode的指針賦值給弧尾頂點(diǎn)的二叉樹節(jié)點(diǎn)指針并且把弧頭頂點(diǎn)的firstout指針賦值給弧尾頂點(diǎn)的firstout指針,最后釋放弧頭頂點(diǎn)的firstin弧節(jié)點(diǎn)和弧頭頂點(diǎn);
s22、利用并聯(lián)歸并,依次計(jì)算頂點(diǎn)的出度,如果頂點(diǎn)的出度大于1則利用firstout域把以該頂點(diǎn)為弧尾的所有弧結(jié)點(diǎn)的弧頭頂點(diǎn)保存在temp1數(shù)組中,對(duì)于temp數(shù)組中的頂點(diǎn)都按照以下步驟執(zhí)行,求該頂點(diǎn)為弧尾的第一個(gè)弧結(jié)點(diǎn)的弧頭頂點(diǎn),計(jì)算該弧頭頂點(diǎn)的入度,如果該弧頭頂點(diǎn)的入度大于1,則利用firstin域把以該弧頭頂點(diǎn)為弧頭的所有弧結(jié)點(diǎn)的弧尾頂點(diǎn)保存在temp2數(shù)組中,然后遍歷temp1數(shù)組和temp2數(shù)組找出兩個(gè)數(shù)組都包含的頂點(diǎn),把這些頂點(diǎn)合并成一個(gè)頂點(diǎn);其中,合并時(shí):
a)先聲明一個(gè)指向strbinode的指針pbinode,把第一個(gè)頂點(diǎn)的binode字段賦值給pbinode;b)然后取出下一個(gè)頂點(diǎn),分配一個(gè)二叉樹結(jié)構(gòu),其指針為newbinode,把pbinode賦值給newbinode的left字段,把頂點(diǎn)的binode字段賦值給newbinode的right字段,賦值newbinode的operator字段為枚舉元素or,把newbinode賦值給pnode,最后釋放該頂點(diǎn)的firstin和firstout指針?biāo)赶騼?nèi)容和該頂點(diǎn)指針?biāo)赶騼?nèi)容;c)重復(fù)步驟b)直到取出所有頂點(diǎn);
s23、重復(fù)步驟s21、s22,直到十字鏈表只剩下一個(gè)頂點(diǎn),該頂點(diǎn)的binode字段為一顆包含了梯形圖邏輯關(guān)系的二叉樹的根節(jié)點(diǎn)。
進(jìn)一步地,所述步驟s4,具體為:
s41、掃描物理輸入并存儲(chǔ)物理輸入狀態(tài);
s42、利用堆棧原理逐行解釋指令表,直到遇到end指令結(jié)束;
s43、把存儲(chǔ)的物理輸出狀態(tài)更新到物理輸出。
進(jìn)一步地,所述步驟s42的利用堆棧原理逐行解釋指令表,利用堆棧先進(jìn)先出的特點(diǎn)來(lái)實(shí)現(xiàn)指令表的解釋,所述指令表的解釋分4種情況,包括:
(1)對(duì)于ld或ldi指令,將其操作數(shù)壓入堆棧;
(2)對(duì)于out指令,將其操作數(shù)從堆棧中取出;
(3)對(duì)于and、ani、or、ori、anb、orb指令,將其對(duì)象從堆棧中取出,經(jīng)過(guò)邏輯運(yùn)算后存入堆棧;
(4)對(duì)于set、rst指令,改變其操作數(shù)的狀態(tài)。
采用上述技術(shù)方案后,本發(fā)明至少具有如下有益效果:
1、本發(fā)明能夠準(zhǔn)確、有效地把包含復(fù)雜邏輯關(guān)系的梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行;
2、本發(fā)明可結(jié)合emc數(shù)控系統(tǒng)組成軟plc系統(tǒng),軟plc系統(tǒng)具有開放的體系結(jié)構(gòu),可以根據(jù)用戶需求合理選擇硬件,節(jié)省成本。
附圖說(shuō)明
圖1為本發(fā)明一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法的步驟流程圖;
圖2為常見(jiàn)plc梯形圖示例;
圖3為圖2的plc梯形圖映射成的無(wú)環(huán)有向圖示意圖;
圖4為根據(jù)圖3無(wú)環(huán)有向圖建立的十字鏈表;
圖5為本發(fā)明一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法中串聯(lián)歸并的步驟流程圖;
圖6為本發(fā)明一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法中并聯(lián)歸并的步驟流程圖;
圖7為本發(fā)明一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法的指令表解釋器工作的步驟流程圖;
圖8為根據(jù)圖2所得到的指令表。
具體實(shí)施方式
需要說(shuō)明的是,在不沖突的情況下,本申請(qǐng)中的實(shí)施例及實(shí)施例中的特征可以相互結(jié)合,下面結(jié)合附圖和具體實(shí)施例對(duì)本申請(qǐng)作進(jìn)一步詳細(xì)說(shuō)明。
梯形圖時(shí)由一系列圖形化元件通過(guò)水平線和垂直線串并聯(lián)組合而成的具有一定邏輯關(guān)系的圖形表達(dá)式。如圖1所示,本發(fā)明提供了一種將plc梯形圖轉(zhuǎn)換成指令表并解釋執(zhí)行的方法,其具體步驟方法如下面詳細(xì)的描述內(nèi)容。
1、梯形圖的數(shù)據(jù)結(jié)構(gòu)
梯形圖時(shí)由圖符構(gòu)成的,在梯形圖編輯部分,梯形圖每一行作為一個(gè)階級(jí),每個(gè)階級(jí)含有n個(gè)圖符,所以我們?cè)O(shè)計(jì)strrung結(jié)構(gòu)體和strelement結(jié)構(gòu)體作為梯形圖的數(shù)據(jù)結(jié)構(gòu),以記錄梯形圖各元件的數(shù)據(jù)信息,strrung結(jié)構(gòu)體和strelement結(jié)構(gòu)體如下所示:
其中數(shù)組element保存了階級(jí)中所有元件,rung_width表示每個(gè)階級(jí)中元件的個(gè)數(shù),flow_end_type標(biāo)志位表示是子程序結(jié)束還是整個(gè)程序結(jié)束,linecomment表示行注釋字符串。
其中ele_type表示元件的類型,var_type表示變量的類型,var_num保存變量的值,source_num保存元件的值。
2、建立十字鏈表,如圖4所示:
梯形圖的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)的是各個(gè)元件的數(shù)據(jù)信息,并沒(méi)有包含元件之間的串并聯(lián)邏輯關(guān)系,所以需要根據(jù)梯形圖建立十字鏈表。通過(guò)自上而下、自左而右遍歷梯形圖,把除了空元件和導(dǎo)線元件的其他元件視為十字鏈表的頂點(diǎn),十字鏈表頂點(diǎn)的數(shù)據(jù)結(jié)構(gòu)如下所示:
firstin表示指向以該頂點(diǎn)作為弧頭的第一個(gè)弧結(jié)點(diǎn),firstout表示指向以該頂點(diǎn)作為弧尾的弧結(jié)點(diǎn)。binode是二叉樹的結(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。ele_type表示頂點(diǎn)對(duì)應(yīng)元件的元件類型;var_type表示變量的類型;num表示頂點(diǎn)對(duì)應(yīng)元件的標(biāo)號(hào)。十字鏈表的頂點(diǎn)數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)了元件的數(shù)據(jù)信息,而元件的串并聯(lián)關(guān)系則通過(guò)十字鏈表弧結(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),十字鏈表弧結(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)如下所示:
tailvex表示弧尾頂點(diǎn)在梯形圖中的位置,headvex表示弧頭頂點(diǎn)在梯形圖中的位置,headlink表示指向與此弧的弧頭相同的下一條弧,taillink表示指向與此弧弧尾相同的下一條弧。
3、建立二叉樹
梯形圖與指令表之間是一一對(duì)應(yīng)的,通過(guò)研究發(fā)現(xiàn)梯形圖中每個(gè)梯級(jí)的圖符的邏輯關(guān)系是一種層次結(jié)構(gòu),而這種層次結(jié)構(gòu)容易用數(shù)據(jù)結(jié)構(gòu)中的樹來(lái)表達(dá),把每個(gè)梯級(jí)用二叉樹這種結(jié)構(gòu)表達(dá)后,整個(gè)梯形圖就是多個(gè)二叉樹的集合。二叉樹結(jié)構(gòu)體strbinode如下所示:
該結(jié)構(gòu)體中,left是二叉樹結(jié)點(diǎn)的左葉子結(jié)點(diǎn)指針,right是二叉樹右葉子結(jié)點(diǎn)指針,parent是二叉樹結(jié)點(diǎn)的父親結(jié)點(diǎn)指針,operator是用于保存邏輯關(guān)系。
因?yàn)槭宙湵淼捻旤c(diǎn)數(shù)據(jù)結(jié)構(gòu)包含了二叉樹結(jié)構(gòu)體指針,而十字鏈表的弧結(jié)點(diǎn)存儲(chǔ)了梯形圖的串并聯(lián)邏輯關(guān)系,所以我們可以通過(guò)化簡(jiǎn)十字鏈表來(lái)建立二叉樹,其步驟如下所示:
1)串聯(lián)歸并,以圖2所示的plc梯形圖為例,其映射的無(wú)環(huán)有向圖如圖3所示,依次計(jì)算十字鏈表頂點(diǎn)的入度,頂點(diǎn)x2的入度為1,由該頂點(diǎn)結(jié)構(gòu)的firstin域得到以該頂點(diǎn)為弧頭的第一個(gè)弧節(jié)點(diǎn),由弧節(jié)點(diǎn)得到弧尾頂點(diǎn)x1,接著計(jì)算該弧尾頂點(diǎn)x1的出度和入度,因?yàn)榛∥岔旤c(diǎn)的出度為1且入度小于等于1,則弧尾頂點(diǎn)x1和弧頭頂點(diǎn)x2可以合并為一個(gè)頂點(diǎn);其中,串聯(lián)歸并的步驟流程圖如圖5所示。
2)并聯(lián)歸并,依次計(jì)算頂點(diǎn)的出度,如果頂點(diǎn)的出度大于1則利用firstout域把以該頂點(diǎn)為弧尾的所有弧結(jié)點(diǎn)的弧頭頂點(diǎn)保存在temp1數(shù)組中,對(duì)于temp數(shù)組中的頂點(diǎn)都按照以下步驟執(zhí)行,求該頂點(diǎn)為弧尾的第一個(gè)弧結(jié)點(diǎn)的弧頭頂點(diǎn),計(jì)算該弧頭頂點(diǎn)的入度,如果該弧頭頂點(diǎn)的入度大于1,則利用firstin域把以該弧頭頂點(diǎn)為弧頭的所有弧結(jié)點(diǎn)的弧尾頂點(diǎn)保存在temp2數(shù)組中,然后遍歷temp1數(shù)組和temp2數(shù)組找出兩個(gè)數(shù)組都包含的頂點(diǎn),合并時(shí)a)先聲明一個(gè)指向strbinode的指針pbinode,把第一個(gè)頂點(diǎn)的binode字段賦值給pbinode,b)然后取出下一個(gè)頂點(diǎn),分配一個(gè)二叉樹結(jié)構(gòu),其指針為newbinode,把pbinode賦值給newbinode的left字段,把頂點(diǎn)的binode字段賦值給newbinode的right字段,賦值newbinode的operator字段為枚舉元素or,把newbinode賦值給pnode,最后釋放該頂點(diǎn)的firstin和firstout指針?biāo)赶騼?nèi)容和該頂點(diǎn)指針?biāo)赶騼?nèi)容,c)重復(fù)步驟b)直到取出所有頂點(diǎn)。并聯(lián)歸并的步驟流程圖如圖6所示;
3)重復(fù)步驟1)和步驟2)直到十字鏈表只剩下一個(gè)頂點(diǎn),該頂點(diǎn)的binode字段為一顆包含了梯形圖邏輯關(guān)系的二叉樹的根節(jié)點(diǎn)。
通過(guò)后序遍歷所建立的二叉樹即可得到如圖8所示的指令表。
3、指令表解釋器
本發(fā)明是利用堆棧來(lái)實(shí)現(xiàn)邏輯運(yùn)算的解釋,堆棧是一種先進(jìn)先出的線性表,即先進(jìn)去的元素最后才出來(lái),我們將利用堆棧此特點(diǎn)來(lái)解釋指令表。我們可以將指令表的指令碼大致分成4類,如下所示:
1)將其操作數(shù)存入堆棧,例如:ld、ldi等;
2)將其操作數(shù)從堆棧中取出,例如:out;
3)將其對(duì)象從堆棧中取出,經(jīng)過(guò)邏輯運(yùn)算后存入堆棧,例如:and、ani、or、ori、anb、orb等;
4)改變其操作數(shù)的狀態(tài),例如:set、rst等。
如圖7所示,解釋指令表時(shí),我們先掃描所有物理輸入并存儲(chǔ)所有物理輸入的狀態(tài),然后逐行解釋指令表,按照以上4類情況操作堆棧,直到遇到end指令結(jié)束,最后把存儲(chǔ)的輸出狀態(tài)更新到物理輸出。
盡管已經(jīng)示出和描述了本發(fā)明的實(shí)施例,對(duì)于本領(lǐng)域的普通技術(shù)人員而言,可以理解的是,在不脫離本發(fā)明的原理和精神的情況下可以對(duì)這些實(shí)施例進(jìn)行多種等效的變化、修改、替換和變型,本發(fā)明的范圍由所附權(quán)利要求及其等同范圍限定。