羅 驍 王庭有 張才勇
(昆明理工大學(xué)機(jī)電工程學(xué)院)
昆明理工大學(xué)機(jī)電工程學(xué)院張才勇設(shè)計(jì)搭建的小微型嵌入式PLC 以STM32MCU 為CPU的核心硬件,采用層疊式設(shè)計(jì),由3 塊PCB 板疊加構(gòu)成。 頂層PCB 板為整個(gè)PLC 的核心板塊,集成MCU 芯片、EEPROM 芯片、485 通信接口和輸入輸出提示燈。 二層PCB 板為PLC 與控制對(duì)象的輸入輸出交流層,包含光耦輸入、繼電器輸入等外設(shè)元件。 底層PCB 板是PLC 的電源層,集成了交流轉(zhuǎn)直流的多個(gè)降壓模塊,可為PLC 和外接模塊供電。該小微型嵌入式PLC 的特點(diǎn)在于有極強(qiáng)的通用性和定制性,用戶可以根據(jù)自身需求的不同, 對(duì)PLC 的核心板進(jìn)行裁剪或添加外設(shè),即可在不同控制情景下實(shí)現(xiàn)用途。
目前, 小微型PLC 具有較高的市場(chǎng)占有率,并以其較高的性價(jià)比逐漸替代傳統(tǒng)小型PLC 設(shè)備,相比于現(xiàn)有的整塊式PLC,開(kāi)發(fā)層疊結(jié)構(gòu)的PLC 擴(kuò)展性更好、更靈活。 因此筆者對(duì)層疊結(jié)構(gòu)的小微型嵌入式PLC 上下位機(jī)指令一致性進(jìn)行研究,并設(shè)計(jì)實(shí)驗(yàn)驗(yàn)證指令的實(shí)現(xiàn)情況。
根據(jù)國(guó)際電工委員會(huì)制定的工業(yè)控制編程語(yǔ)言標(biāo)準(zhǔn)IEC 1131-3,PLC 的編程語(yǔ)言包括以下5 種:梯形圖語(yǔ)言(LD)、指令表語(yǔ)言(IL)、功能模塊圖語(yǔ)言(FBD)、順序功能流程圖語(yǔ)言(SFC)和結(jié)構(gòu)化文本語(yǔ)言(ST)[1]。其中,指令表語(yǔ)言是與匯編語(yǔ)言類似的一種助記符編程語(yǔ)言,和匯編語(yǔ)言一樣由操作碼和操作數(shù)組成。 在無(wú)計(jì)算機(jī)的情況下,適合采用PLC 手持編程器對(duì)用戶程序進(jìn)行編制。 同時(shí),指令表語(yǔ)言與梯形圖語(yǔ)言一一對(duì)應(yīng),在PLC 編程軟件下可以相互轉(zhuǎn)換[2]。
由于其他編程語(yǔ)言編寫的控制程序最終都需要轉(zhuǎn)換為指令序列來(lái)執(zhí)行,并且利用指令表語(yǔ)言編寫的程序通??梢砸宰罡咚俣冗\(yùn)行[3~5],因此筆者選擇指令表語(yǔ)言作為PLC 編程軟件使用的編程語(yǔ)言。
1.2.1 基本邏輯運(yùn)算
PLC 中最基本的運(yùn)算方式是邏輯運(yùn)算,基本邏輯運(yùn)算包含“與”、“或”、“非”3 種運(yùn)算,其余的邏輯運(yùn)算均以此為基礎(chǔ)實(shí)現(xiàn),因此首先要實(shí)現(xiàn)基本邏輯運(yùn)算(圖1)。
1.2.2 邏輯堆棧
邏輯堆棧是PLC 在進(jìn)行邏輯運(yùn)算時(shí)用于存儲(chǔ)運(yùn)算結(jié)果和中間值的區(qū)域, 是PLC 運(yùn)行的基礎(chǔ),一般采用整段連續(xù)的區(qū)域作為邏輯堆棧[6]。棧深關(guān)系到PLC 的運(yùn)算能力,將PLC 的邏輯堆棧棧深和指針定義如下:
圖1 基本邏輯運(yùn)算定義
上述代碼定義了邏輯堆棧的棧深為40,頂層作為運(yùn)算結(jié)果的存儲(chǔ)區(qū), 余下39 層用于存儲(chǔ)運(yùn)算的中間值。 使用棧頂指針logical_array_pointer操作堆棧,當(dāng)有數(shù)據(jù)入棧時(shí),丟棄底層數(shù)據(jù),將堆棧內(nèi)容依次下移,騰空棧頂單元壓入數(shù)據(jù);當(dāng)有數(shù)據(jù)出棧時(shí),彈出頂層數(shù)據(jù),將堆棧內(nèi)容依次上移,棧底單元補(bǔ)0。
定義邏輯堆棧后,需要PLC 來(lái)實(shí)現(xiàn)對(duì)堆棧的操作,因此要定義操作堆棧的指令,如圖2 所示。
圖2 部分堆棧操作指令定義
為了保證PLC 嚴(yán)格按照所編指令進(jìn)行工作,需要將PLC 能夠識(shí)別的數(shù)字編碼與編程軟件所用的操作碼和操作數(shù)一一對(duì)應(yīng)起來(lái),表1 給出了部分操作碼和操作數(shù)對(duì)應(yīng)的編碼。 將表1 所示的操作碼(操作數(shù))對(duì)應(yīng)的編碼寫入文件ins.m 中,并加入MATLAB,以保證編寫出的PLC 指令能夠正確編譯。
表1 部分操作碼和操作數(shù)對(duì)應(yīng)的編碼
PLC 要執(zhí)行指令, 首先需要識(shí)別指令函數(shù),具體實(shí)現(xiàn)方法為:每當(dāng)執(zhí)行完任一指令后,指向用戶程序存儲(chǔ)區(qū)的指針會(huì)根據(jù)本條指令的占用內(nèi)存自動(dòng)向下偏移m(m=1,3,6)個(gè)字節(jié),以達(dá)到正確取址和執(zhí)行下一條指令的目的。 例如執(zhí)行只有操作碼的LPS 指令,執(zhí)行指令后指針向下偏移1 個(gè)字節(jié), 繼續(xù)執(zhí)行下一條指令。 若執(zhí)行OUT Q0 指令, 操作碼OUT 占1 個(gè)字節(jié),Q0 占2 個(gè)字節(jié),則執(zhí)行該指令后指針向下偏移3 個(gè)字節(jié)。 然后編寫ins_exc.c 文件,在其中定義用戶程序執(zhí)行函數(shù)user_pro_exc (), 該函數(shù)的執(zhí)行流程如圖3所示。
圖3 user_pro_exc()函數(shù)執(zhí)行流程
如圖3 所示,執(zhí)行user_pro_exc()函數(shù)時(shí),首先判斷用戶程序存儲(chǔ)區(qū)內(nèi)是否有用戶程序,如果用戶程序指針user_pro_storage_p 指向的地址內(nèi)容為0,則說(shuō)明沒(méi)有用戶程序,結(jié)束函數(shù)執(zhí)行;反之,如果不為0,則執(zhí)行construction()函數(shù),該函數(shù)的執(zhí)行流程如圖4 所示。
圖4 construction()函數(shù)執(zhí)行流程
如圖4 所示,開(kāi)始執(zhí)行construction()函數(shù)后,首先執(zhí)行選擇函數(shù)select()對(duì)用戶程序中的指令進(jìn)行選擇,對(duì)于沒(méi)有操作數(shù)的指令,如LPS 指令等直接執(zhí)行后即結(jié)束該函數(shù)。 對(duì)于既有操作碼又有操作數(shù)的指令, 如LD I0 指令等進(jìn)一步匹配到sub_select()函數(shù)后再執(zhí)行操作,sub_select()函數(shù)能為這些指令提供I、Q、M、C、T 等操作數(shù)。
完成PLC 對(duì)函數(shù)指令的識(shí)別工作后,即可達(dá)到使PLC 正確執(zhí)行上位機(jī)用戶程序指令的目的。
使用MATLAB GUI 工具設(shè)計(jì)簡(jiǎn)單的編程界面(圖5),實(shí)現(xiàn)PLC 程序的編程、編譯和下載功能。 該編程軟件界面左側(cè)為STL 指令編寫區(qū)域,在此區(qū)域內(nèi)編寫所需的用戶程序;右側(cè)是編譯提示區(qū)域, 當(dāng)指令編寫完成后點(diǎn)擊編譯按鈕,編譯提示區(qū)域會(huì)顯示編譯后的十六進(jìn)制數(shù)。
圖5 PLC 編程軟件界面
設(shè)計(jì)實(shí)驗(yàn)對(duì)PLC 的邏輯指令進(jìn)行驗(yàn)證,實(shí)驗(yàn)指令包括:觸點(diǎn)指令LD、A、O、LDN、AN、ON;邏輯堆棧指令A(yù)LD、OLD、LPS、LRD、LPP; 輸出指令OUT。
在PC 端的PLC 編程軟件中輸入指令表指令,編譯如圖6 所示。
圖6 PLC 指令
在4 個(gè)輸出端口上各連接一個(gè)LED,當(dāng)輸出端口得電時(shí)二極管發(fā)光,輸出端口不得電時(shí)二極管熄滅。
該實(shí)驗(yàn)中設(shè)計(jì)多種接通方案, 具體如下:僅I0 或I3 得電時(shí),Q3 得電,其余回路不接通。 I0 和I2 得電時(shí),僅Q3 得電,其余回路不接通;若同時(shí)再接通I4、I5 或I6,則在Q3 保持燈亮的情況下,分別有Q0、Q1 或Q2 燈亮,說(shuō)明串聯(lián)電路接通。I0和I3 得電時(shí)的情況與I0 和I2 得電情況一致。
通過(guò)實(shí)驗(yàn),觀察到如下現(xiàn)象:
a. 啟動(dòng)PLC,按下I0,Q3 得電,對(duì)應(yīng)的LED點(diǎn)亮,其余LED 保持熄滅;斷開(kāi)I0,按下I3,Q3得電,對(duì)應(yīng)的LED 點(diǎn)亮,其余LED 保持熄滅。
b. 接通I0 和I2 的同時(shí),再按下I4,Q3 和Q0得電,對(duì)應(yīng)的LED 點(diǎn)亮;斷開(kāi)I4,接通I5,Q3 和Q1 得電,對(duì)應(yīng)的LED 點(diǎn)亮,其余LED 保持熄滅;斷開(kāi)I5,接通I6,Q3 和Q2 得電,對(duì)應(yīng)的LED 點(diǎn)亮,其余LED 保持熄滅。
c. 接通I0 和I3 的同時(shí),再按下I4,Q3 和Q0得電,對(duì)應(yīng)的LED 點(diǎn)亮;斷開(kāi)I4,接通I5,Q3 和Q1 得電,對(duì)應(yīng)的LED 點(diǎn)亮,其余LED 保持熄滅;斷開(kāi)I5,接通I6,Q3 和Q2 得電,對(duì)應(yīng)的LED 點(diǎn)亮,其余LED 保持熄滅。
綜上所述,實(shí)驗(yàn)結(jié)果與設(shè)計(jì)方案一致,說(shuō)明使用筆者設(shè)計(jì)的指令表語(yǔ)言編程器編寫的用戶指令在下位機(jī)PLC 中得到了正確執(zhí)行。
筆者使用MATLAB 編寫出的PLC 指令表語(yǔ)言編程軟件能夠正確進(jìn)行指令的編譯,并且能夠在STM32MCU 的下位機(jī)PLC 上正確執(zhí)行, 說(shuō)明上位機(jī)和下位機(jī)的指令具有一致性,是一個(gè)能實(shí)際應(yīng)用的編程軟件。