[摘 要] 不同的PLC系統(tǒng)對多字節(jié)變量的存儲有大端順序與小端順序兩種字節(jié)順序,在不同字節(jié)順序的PLC系統(tǒng)間移植程序必須注意這一問題,需要針對性地做出改變才能保證移植的正確性。旨在通過案例來探討正確處理多字節(jié)變量的程序在移植時的方法。
[關 鍵 詞] PLC程序移植;字節(jié)順序;大端順序;小端順序
[中圖分類號] G712 [文獻標志碼] A [文章編號] 2096-0603(2017)20-0054-02
一、引言
PLC是一種專門為在工業(yè)環(huán)境下應用而設計的數(shù)字運算操作的電子裝置,實質(zhì)上是一種專門用于工業(yè)控制的計算機,其硬件結(jié)構基本上與微型計算機相同。PLC性能穩(wěn)定,能在惡劣的環(huán)境中可靠工作,是被公認為最可靠的工業(yè)控制設備之一。自從1969年美國研制出第一臺PLC,幾十年來PLC發(fā)展迅速,已成為自動化控制的主流設備。
為了貫徹職業(yè)教育與產(chǎn)業(yè)對接,教學和生產(chǎn)實踐對接的指導方針,目前很多中職學校的機電專業(yè)都開設了PLC課程。但由于行業(yè)標準出現(xiàn)較晚,不同廠家PLC的指令集往往千差萬別,且硬件結(jié)構往往也不相同,所以,從事PLC的編程或教學人員在使用不同的PLC時,都會遇到程序移植問題。PLC程序在不同PLC間進行移植時需要考慮的問題很多,其中字節(jié)順序就是重點考慮的問題之一。本文就以PLC教學實訓時的一個典型實例來探討這一問題。
二、PLC程序移植案例
(一)項目簡介
目前中職的PLC教學往往都是根據(jù)從生產(chǎn)實踐中提煉出來的一些典型案例開展的,其中彩燈控制是PLC實訓中的一個常見項目。該項目通常是通過使用計時器和移位指令來實現(xiàn),是一個用來訓練計時器和移位指令的典型案例。筆者在PLC教學實訓時還基于這個實例開展過譯碼指令和計數(shù)器的綜合實訓,最初是在三菱的FX2N PLC上實現(xiàn)的,最近在一次實訓中需要將這個程序移植到西門子S7-200 PLC上,就遇到了由于兩個系統(tǒng)的字節(jié)順序不同造成錯誤的情況,下面就通過這次排錯來跟大家一起探討一下PLC字節(jié)順序的有關問題。
首先我介紹一下實訓用的項目和利用譯碼指令、計數(shù)器指令實現(xiàn)的思路。項目是n(n小于或等于PLC輸出點數(shù),本案例為說明雙字節(jié)變量的移植取n等于9)只LED彩燈,要求依次點亮并循環(huán),時間間隔為1s,使用兩個按鈕控制啟動和結(jié)束。編程的思路是對1s脈沖進行計數(shù),對計數(shù)器的當前值進行譯碼,譯碼的結(jié)果輸出到輸出繼電器。
(二)FX2N平臺下的實現(xiàn)
先說一下在FX2N上具體的實現(xiàn)方法。啟動按鈕和停止按鈕分別連接到輸入端子X0和X1,9只彩燈分別連接到輸出端子Y0到Y(jié)10。程序中由軟元件X000、Y000和M0構成典型的啟動停止控制,其中M0作為運行標志。接下來的程序中利用16位計數(shù)器C0對1s脈沖進行計數(shù),根據(jù)LED彩燈的個數(shù)設置計數(shù)器的設定值為9,利用C0的常開觸點對C0復位來實現(xiàn)循環(huán)點亮。運行過程中將C0的當前值譯碼與結(jié)果直接輸出到輸出繼電器。具體程序如圖1所示。
(三)移植到S7-200 PLC的過程和遇到的問題
這個程序還是很簡單的,現(xiàn)在介紹一下將這個程序移植到西門子S7-200型PLC的過程以及所遇到的問題。
首先要對用到的指令和軟元件進行移植,有些指令和軟元件是可以直接替換的,上面程序中的X000和X001要分別改為I0.0和I0.1,M0要改為M0.0,M8013要改為M0.5,計數(shù)器C0 K10要改為CTU類型的C0,PV設置為10,這些軟元件在兩種PLC中有著簡單的對應關系,可以直接替換。而譯碼指令在兩種PLC中的用法并不完全相同,雖然都是譯碼,功能都是對輸入的數(shù)據(jù)n,計算2n輸出結(jié)果,但是FX2N中的譯碼指令DECO是16位指令,能夠?qū)⒃吹刂罚ㄗ周浽┑牡蚽位或源地址(位軟元件)開始的n位譯碼到目標地址(字地址,此時n的最大值為4)或從目標地址(位地址,此時n的最大值為8)起的2n位;而S7-200中的譯碼指令DECO的功能是將輸入的字節(jié)的低4位譯碼到輸出的字地址單元,將其對應位置1。應該注意到二者的輸入不同,前者比較靈活,既可以是n位的位軟元件,也可以是字軟元件的低n位,而后者則相對單一,只能從字節(jié)輸入,輸出到字,這就導致16位的計數(shù)器的當前值并不能直接作為譯碼指令的輸入,必須將計數(shù)器當前值首先傳送到一個字節(jié)中。筆者在S7-200 PLC的指令集中找到了兩條指令,一條是字傳送指令MOV_W,另一條是整數(shù)轉(zhuǎn)換為字節(jié)指令ITB,由于以前在FX2N的指令集中只有傳送指令,因此最后選用了與其對應的傳送指令MOV_B來實現(xiàn)。
經(jīng)過上面的一系列處理得到了下面的PLC梯形圖程序,如圖2所示。
但是程序在運行時出問題了,竟然沒有輸出正確的結(jié)果。錯誤的原因在哪里呢,通過監(jiān)視運行發(fā)現(xiàn),問題出在網(wǎng)絡3,VB0的值竟然永遠是0,所以導致QW0一直是1,也永遠只有Q1.0是1,即只有第9個彩燈是亮的。怎么會這樣呢,繼續(xù)往前查,發(fā)現(xiàn)VW0的值在運行過程中是正常從0到9變化的,而將VB0中的數(shù)值譯碼后就不對了,這說明問題就出在VB0上。另外,為什么QW0是1的時候,是Q1.0為1,而不是Q0.0呢?
(四)對移植時出現(xiàn)的錯誤分析
VB0永遠是0是什么原因造成的呢?為什么QW0是1的時候Q1.0為1呢?這兩個問題都要用長度為字的數(shù)據(jù)在系統(tǒng)中存儲時的字節(jié)順序來解釋了。
什么是字節(jié)順序呢?字節(jié)順序是指占內(nèi)存多于一個字節(jié)的數(shù)據(jù)類型中的各個字節(jié)在內(nèi)存中的存放順序,如1個字包含2個字節(jié),字中的字節(jié)順序有兩種,一種格式是高位字節(jié)存儲在低地址,低位字節(jié)存儲在高地址,這被稱為大端順序;而另一種則正好相反,低位字節(jié)存儲在低地址,高位字節(jié)存儲在高地址,這種順序稱為小端順序。
因為不同的機器類型可能采用不同的字節(jié)順序,所以在不同系統(tǒng)間移植程序時,對多字節(jié)數(shù)據(jù)類型必須弄清楚系統(tǒng)的字節(jié)順序。
上面的程序之所以在FX2N上能正確運行,而在S7-200系統(tǒng)上就不能運行,其原因就是這兩個系統(tǒng)采取了不同的字節(jié)順序,F(xiàn)X2N采用的字節(jié)順序是小端順序,而S7-200則采用了大端順序,VB0永遠是0和QW0是1的時候Q1.0為1這兩個問題都是由于這個原因造成的。
(五)正確的移植方法和程序
在圖1所示的FX2N程序中,用到的多字節(jié)軟元件有C0和K4Y000都是16位的,即雙字節(jié)的字元件,其儲存格式采用小端順序,其中C0在程序中的取值范圍是0到9,譯碼指令將C0的低4位譯碼并將結(jié)果輸出到K4Y000。這兩個字元件在S7-200中對應的變量分別是C0和QW0,他們也是雙字節(jié)的,采用的是大端順序,譯碼指令根據(jù)輸入的字節(jié)變量的低4位所表示的位號,將輸出字QW0的相應位置為1。
這里有兩點需要注意,一是兩個系統(tǒng)的譯碼指令接受的輸入類型不同,F(xiàn)X2N中的譯碼指DECO可以直接使用字元件,但是S7-200中的譯碼指令DECO只能接受字節(jié)變量;二是S7-200采用大端順序,需要譯碼的數(shù)據(jù)0到9存在C0的高位字節(jié),而0到7譯碼的結(jié)果儲存在QW0的高位字節(jié),8和9的譯碼結(jié)果則存在QW0的低位字節(jié)。
第一個問題在前面已經(jīng)解決了,所以現(xiàn)在只需要解決第二個問題:將QW0的高位字節(jié)和低位字節(jié)交換。一種方法是譯碼指令不直接輸出到QW0,而是輸出到一個方便分別存取高低位字節(jié)的中間變量,然后將其低位字節(jié)傳送到QW0的高位字節(jié)QB0,低位字節(jié)傳送到QW0的低位字節(jié)QB1;另一種方法是利用S7-200的字節(jié)交換指令SWAP,直接將QW0的高低位字節(jié)交換。顯然第二種方法更為簡潔一些,但是需要對指令集要比較熟悉,第一種方法則適合對指令集不熟悉或?qū)敵龆丝谟刑貏e要求的情形。在此,筆者采用了第二種方法對程序進行了改寫。最后得到的移植后的程序如圖3所示。
三、結(jié)束語
在不同的PLC系統(tǒng)間移植程序是比較復雜的問題,要想正確移植程序,除了要弄清不同PLC系統(tǒng)的指令和變量(軟元件)的對應關系及不同之處以外,還必須弄清要移植的程序中用到了哪些多字節(jié)的變量,它們在程序中是如何使用的,以及原平臺和目標平臺字節(jié)順序分別是哪種,然后根據(jù)字節(jié)順序?qū)Χ嘧止?jié)變量進行必要的轉(zhuǎn)換。只有這樣才能避免由于字節(jié)順序不同造成的錯誤。這個例子也提示我們在PLC的編程過程中既要注意指令的學習,還應該重視PLC系統(tǒng)底層的實現(xiàn)。