車健生 吳雪霏
(沈陽現代制造服務學校 遼寧省沈陽市 110148)
隨著順序功能圖在PLC梯形圖中的廣泛應用,“以經驗法為主的設計方法存在設計周期長,不易掌握,程序可讀性差”[1]等問題有了很大緩解。但對于一個中大型PLC編程設計,順序功能圖的梯形圖編程也暴露出一些問題。如與經驗法比較上手容易,但程序代碼數量大多超過后者。轉換條件與輸出狀態混在一個SCR—SCRE嵌套中,條理不夠清楚;步的轉換條件、輸出狀態語句數量隨著步的復雜程度而變化,引起程序個別點處臃腫,整體不均勻。這些都會造成順序功能圖結構不清晰,直觀性、可讀性受到嚴重影響。把一個程序分解為若干個子程序,是解決這個問題的一個重要途徑,“運用函數”或子程序“是程序的首要組織手段”,它給程序“帶來更好的可讀性、可維護性和可重用性”[2]。將一個大程序按照一定的規范分解為若干小程序模塊,稱之為模塊化設計,顯然,這個規范的合理性、可操作性是重中之重。
在計算機科學發展史上,結構化程序設計的出現是一個里程碑的事件,結構化程序設計最基本原則是:任何程序都可以由三種基本流程結構構成,即順序結構、分支結構和循環結構。在PLC編程發展史,順序功能圖(SFC)能夠脫穎而出、備受關注,也在于它關注程序的結構。順序功能圖主要由步、有向連線、轉換、轉換條件和輸出狀態組成。將系統工作過程劃分成若干順序相連的、由被控對象工作狀態變化所決定的步;步的活動狀態的轉換由轉換條件來實現。這是順序功能圖的“形”,它的“神”是PLC程序設計由此實現了把所有程序看作是由單序列、選擇序列和并列序列三種基本結構組成的,如圖1、圖2和圖3所示。一定程度上有效地避免經驗設計法中的試探性和隨意性,提高程序的可讀性和可維護性。
如果一個梯形圖編程模塊化規范能夠涵蓋這三種基本結構,那么這個規范就是完備的。以下模塊化規范的構建均是在討論這三種基本結構的基礎上,此外,規范仍然要保持梯形圖編程直觀性的特點。
順序功能圖用梯形圖編程實現一般有三種方法,一是使用啟保停電路的順序控制設計方法;二是使用SCR指令的順序控制設計方法;三是使用計數變量的順序控制設計方法[3]。其中,方法一在一個網絡中描述一個步,當某個轉換條件或狀態輸出繁多時,這個網絡就會臃腫復雜;方法二由于有些PLC沒有專用的SCR順序控制繼電器而有所受限,同時SCR、SCRE對于每一“步”都要占用兩個網絡的開銷;方法三對于表達并列順序功能圖,通過一個計數變量描述所有步,計數變量某一時刻的值對應活動步編號,這對并列順序功能圖同時存在兩個以上活動步的編程是有欠缺的,如果強行合并并列步為一步,會破壞順序功能圖的條理性。
在總結上述三種方法優點基礎上,本規范主程序,用Mx.y位存儲器依次表示順序步,Mx.y位存儲器值為1時,對應的步為活動步。每一步占用一個網絡,均由調用轉換條件子程序SBR_i和調用輸出狀態子程序Output_State兩條指令組成(以上x,y分別為字節與位編號,i為子程序序號),圖2選擇序列順序功能圖的主程序如圖4。

圖1:單序列

圖2:選擇序列

圖3:并列序列

圖4:選擇序列主程序片段

圖5:分支點步轉換條件子程序SBR_0

圖6:并列步轉換條件子程序SBR_0

圖7:接收狀態位組數據子程序片段

圖8:數字字符串轉數組部分梯形圖
調用轉換條件子程序指令有著相同的結構,以SBR_0為例,左邊輸入端Current聯結當前步M0.0,右邊輸出端Forward聯結去向步M0.1 和步M0.4,指令盒清楚地表明順序功能圖中步轉換的來龍去脈。主程序注重的是程序主體流程脈絡,不去關注子程序具體的實現過程。本規范對順序功能圖的梯形圖編程模塊化處理具有主次清楚、層次分明的特點。
規范中,每個條件轉換子程序都由條件邏輯觸發目標步狀態寄存器,接著復位當前活動步狀態寄存器兩部分指令構成。轉換條件滿足時,對目標步狀態位置1,并且對當前步狀態位清0,從而完成當前步到目標步活動狀態的轉變。圖2選擇序列分支點與圖3并列序列并列節點對應的轉換條件子程序SBR_0 分別如圖5和圖6所示。
在條件轉換子程序中Current變量類型設置為IN_OUT,Forward變量類型設置為OUT,這樣子程序能接收主程序調用時傳遞的步狀態位值,也能在轉換條件結束時傳達出當前活動狀態停止的信息。子程序與主程序只在這兩個通道上發生數據交換,實現了子程序與主程序的完全隔離。子程序可隨意使用局部變量,而不用顧及與主程序中變量重名、沖突等問題。如果條件相同,條件轉換子程序可以通用,被不同步所調用,例如圖1的順序功能圖的梯形圖中SBR_0與SBR_2是相同的,可只保留一個,從而提高了條件轉換子程序模塊的復用性。

圖9
順序功能圖每步輸出狀態雖然無外乎Q位寄存器串并聯的組合,每步均有,個別處數量龐大且無序,影響順序功能圖結構性和可讀性。這個看似錯綜復雜的問題可以用一個描寫每步輸出狀態的數組,加上一個數組上運行的通用程序予以處理。
順序功能圖畫出之前,一般先列出系統輸入輸出狀態表,狀態表用來確定順序功能圖的每一步,以及每一步的輸出狀態。狀態表中的輸出狀態可在程序初始化時存入一個二維數組,數組是以步編號為行號,將步狀態中位對應數組元素,每步狀態全部位對應數組的一行。活動步輸出狀態時,以當前步編號為行號,在數組中提取一行數組數據,輸出給Q字節、字或雙字寄存器。程序由下面幾個部分組成。
本程序以每一步輸出狀態為步序號的ASCII二進制數為例,如圖7所示。數組初始化程序以直觀、常規方法接收狀態數據,先是利用STR_CPY指令接收第一串數字字符串,然后再通過STR_CAT附加第二行、第三行、……字符串。不失一般性地約定:數據之間用逗號加空格隔開,第二行開始,追加數據以逗號開頭。習慣上一行數據表示一個步狀態,但也可由多個指令完成。程序假定占用VB2000開始的單元(建議使用高端不常用地址),用于以數字字符串形式保存這批狀態位數據。
數字字符串轉存數組,主要過程是在循環控制指令FOR,利用字符串轉換整數指令S_I,對數字字符串進行整數轉換操作;通過字符搜索指令CHR_FIND,依次推進搜索逗號,把逗號位置賦給AC0,從下一位置開始字符串轉換整數操作,結果保存在AC1中,然后存入指定的數組元素中。主要程序片段如圖8。
對于無數組體系的PLC,如S7-200系列等可按下面方式進行數組的訪問。本研究約定二維數組是以行優先的一維數組方式進行的存儲,二維下標[i, j]對應的一維下標[ (i-1)*列總數+j ],對于元素以字節單元存儲,某個一維下標也就是這個元素的相對地址(相對數組第1個元素前的位置),從而實現對二維數組元素的訪問。下文中涉及的二維數組元素讀取子程序ARRARY2D_B_out就可以按照這樣原理進行設計。
每個步諸多Q位存儲器的值占用1行數組元素,Q位的低位到高位排列對應數組列號的低到高。步狀態二維數組中活動步狀態提取程序Output_State把每行數組元素組合一個字節、字或雙字,作為函數值返回。本文以輸出字節為例,對于指定步狀態編號State_num,程序中循環從起始列號到終止列號,也就是從左到右,依次讀取數組元素ARRAY[State_num, Column_int],對元素值與1進行比較,等于1時,使用左移位SHL_B指令生成1個以元素列號對應位為1,其它位為0的字節QB_bit;通過邏輯或WOR_B指令把上面的QB_bit累計到輸出狀態字節Output_B中。行號為State_num的一行元素依次處理完畢后,字節Output_B就已存放了這步的輸出狀態,以其作為本子程序的返回值。程序核心部分清單如圖9。
程序基于早期S7-200系列PLC,全部通過上機驗證。上述順序功能圖的梯形圖實現模塊化規范,無論是整體,還是主程序和子程序都保持梯形圖的立身之本——直觀性,延續了順序功能圖成功之基——結構化設計。一個大中型項目往往需要多人合作完成,規范化、模塊化的設計有助于分工協作開發程序。模塊化后,程序斷點容易確定,使得調試程序更為方便,提高了程序可靠性。模塊化的設計,對于相關相似的不同項目,使得開發者只需關注修改不同點的模塊,提高了程序開發的復用性。在PLC順序功能圖設計思想廣泛應用的今天,實現順序功能圖設計的梯形圖編程模塊化規范,對順序功能設計的深入發展具有一定的積極作用。