星爺的大話西游是一部大家耳熟能詳的影片,不僅好看而且賦有很多哲理,讓人看完受益匪淺。比如其中紫霞仙子的“我猜的中開頭,卻猜不中結尾”,就道出了世間之事,即使是神仙也未必能夠都預料的道,所以對于我們這些活躍在熱線的普通人要適應這種“新常態(tài)”以“平常心”待之。閑話少敘,下面說一個熱線的故事吧。
熱線上的客戶編寫了一個很簡單的邏輯程序,程序包括兩個塊。ob1主循環(huán)程序和fb1功能塊程序,fb1在ob1中調用。ob1中對rs_result(m100.2)進行置位操作,在fb1中通過操作out參數ors_result來對rs_result(m100.2)進行復位操作。詳細的程序如圖1、圖2所示。
圖1 ob1程序
圖2 fb1程序
通過上面程序,我們期望實際的運行結果是,如果set_trig(m100.0)為true則對rs_result(m100.2)進行置位操作,如果rset_tri(m100.1)為true則對rs_result(m100.2)進行復位操作。程序簡單吧,結構也很清晰,清楚地我們一眼就能預知結果。
可結果真的是這樣嗎?實際測試后發(fā)現(xiàn),當set_trig(m100.0)為true時,rs_result(m100.2)的輸出結果卻不為1,即無法實現(xiàn)對rs_result(m100.2)的置位操作,如圖3所示。
圖3
顯然,這與我們實際想要實現(xiàn)的功能不符。根據邏輯分析來看,程序本身似乎沒有問題,那么問題出在哪里呢?
讓我們發(fā)動一下我們的小宇宙來分析一下吧,對于network1這個簡單的不能再簡單的語句而言,不可能有錯啊,那問題是不是出在fb塊的調用部分呢?我們來設想一下:當set_trig(m100.0)為true時,程序會對rs_result(m100.2)進行了置位操作,但結果卻是該變量被復位了。也就是說在執(zhí)行fb1塊時又將rs_result(m100.2)復位了,可是在fb1中的復位條件rset_tri(m100.1)并不滿足啊,為什么在執(zhí)行fb1塊后會將rs_result(m100.2)復位了呢?難道是plc有問題?非也非也這可是德國產品啊,質量沒得說。哪問題出在哪呢?
要理解清楚這個問題,我們先要從fb功能塊內部參數傳遞的機制說起。從很多場合我們都可以了解到:fb塊區(qū)別于fc塊主要在于每個fb塊都需要一個指定的背景數據塊,這個指定的背景數據塊用來存放fb塊的實際參數。其工作原理是,對于fb塊定義的in類型接口參數,在fb塊被調用執(zhí)行時,將實參傳遞給背景數據塊中形參的對應地址,并用于fb內部的邏輯運算;對于fb塊定義的out類型接口參數,在fb塊被調用執(zhí)行時將fb內部的邏輯運算結果給出到背景數據塊中形參的對應地址,然后再將背景數據塊中形參的對應地址的值傳遞給實參,得到實際的輸出結果。
根據fb功能塊接口參數傳遞的機制,我們可以看到在fb塊執(zhí)行過程中,輸出rset_tri(m100.1)的值取決于其對應的形參在背景數據塊中的地址db1.dbx2.0,如圖4,而實際的db1.dbx2.0在執(zhí)行fb塊時一直為false,所以每次執(zhí)行完fb塊后,db1.dbx2.0將false賦值給rset_tri(m100.1),所以只要調用了fb1,那么實際得到的rset_tri(m100.1)的結果即為false,即我們上面實際測試時的結果。
圖4
我們可以驗證這個結論,即通過修改db1.dbx2.0的值,可以直接改變輸出參數rset_tri(m100.1)的結果,而不論ob1中是否對rset_tri(m100.1)進行了置位操作,如圖5所示。
圖5
既然我們已經分析出問題出現(xiàn)在fb塊上,那么這個問題如何解決呢?
我們知道對于fb功能塊,除了in、out類型接口參數,還有一個in_out類型接口參數。對于in_out類型的接口參數,在調用執(zhí)行時首先將實參讀入,然后進行邏輯運算,最后再將邏輯運算的結果傳遞給實參進行輸出??梢娤鄬τ趏ut類型接口參數而言,in_out類型接口參數是要先讀入實際參數的值,這樣就可以保持上面的邏輯運算結果不會因為fb塊的調用執(zhí)行而被修改。
所以我們可以將fb1作如下修改,如圖6所示。
圖6 fb1
圖7 修改后在ob1中調用fb1
修改程序后進行測試,結果與預想的邏輯一致,即可以通過set_trig(m100.0)、rset_tri(m100.1)對rs_result(m100.2)進行置位、復位操作,如圖8所示
圖8
現(xiàn)在我們簡單總結一下:fb功能塊在調用時,外部實際參數通過輸入、輸出和輸入/輸出接口傳遞給其背景數據塊對應的地址。在fb內部,程序直接操作背景數據塊地址進行邏輯運算。對于fb功能塊的使用我們要特別注意參數傳遞的規(guī)則。這些規(guī)則很隱蔽,一般不易引起我們的重視,并且在出現(xiàn)問題時,如果不了解這些規(guī)則那就真的是猜的中開頭,猜不中結尾,出錯成為新常態(tài)了。