


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