<object id="ir2le"></object>
  • 加入收藏 在線留言 聯系我們
    關注微信
    手機掃一掃 立刻聯系商家
    全國服務熱線15267534595
    公司新聞
    Smart200如何寫出可重復調用的子程序
    發布時間: 2023-08-10 10:55 更新時間: 2024-12-28 09:10

    200Smart是日式風格的小型PLC,其函數用子程序來實現,叫做SBR。SBR類似于TIA平臺1200的FC,沒有自己的私有數據。

    SBR的用來實現一些不需要保留私有數據的一次調用函數功能,比如一次性的數學計算,如果需要使用前幾次的計算結果,通常可以使用幾種方式傳入SRB,一種是使用接口的InOut,另一種是不使用接口而是直接使用全局變量。但直接使用全局變量的缺點除了不能模塊化,還有不能被重復調用(無法實現多個實例)。

    常規意義上來講SBR多次調用需要注意很多問題。我們與1200比較,1200有DB,1200的FC可以使用DB來區分不同的實例。而200Smart的子程序就只能靠設計者自己來規劃不同的V區來區分不同的實例。

    多次調用還有很多和語法特點有關的注意事項,比如沿指令,在SBR多次調用中就不能使用。其他更讓人頭痛的指令是定時器,當然定時器不論是SBR中還是在主程序里都不能多次調用,這個不是SBR的問題,但通常也會伴隨子程序多次調用出現更多問題,例如:

    1,將使用了實際軟元件的FB程序在OUT指令中的多個位置使用時,將變為雙重線圈。

    2,使用了實際的軟元件的FB程序在多個位置被調用時,有可能無法正常動作。

    歸根到底,200Smart子程序的問題就是V區變量規劃問題,它給設計者帶來了更多和編程無關的管理工作。通常你需要準備幾張紙來手動規劃V區。無論是采用電子表格還是紙,隨著設計的推進,修改V區修改已經調試好的模塊是初學者面臨的棘手而繁瑣的工作。

    在論壇上有篇帖子給我帶來了一些解決200Smart如何才能讓SBR具有類似FB背景數據塊的實現方案思路。

    具體來說就是分配出不同尺寸的連續的V區域,每個區域由一個索引來唯一定位,這樣只要知道了索引就能定位這個區域。每個區域就是一個背景數據塊,可以被SBR分配使用。

    以ST20來說,V區共計8190個字節,如果背景DB需要使用3000個字節,那么開始地址大約是從VB5000開始的。這里面包括了之后要設計的管理段,實際分配給SBR使用的背景DB容量小于這個數量。這些關于DB開始位置、容量、以及適配不同型號PLC的V區*后地址的參數可以被修改而無需修改管理程序。

    有解決思路,那如何知道子程序要使用哪個DB呢?

    工作中我見過德國人的解決思路,需要在每次掃描過程中保證每個子程序按照既定的順序來執行,不能出現條件調用子程序的情況存在。說白了就是在調用程序之前規劃好的V區地址(假設VB800-VB900)存入FC中對應的臨時變量中,FC中都使用該臨時變量來進行邏輯運算或存儲結果數據,*后再將攜帶著結果數據的臨時變量寫入到規劃好的V區變量中(VB800-VB900)中,接下來的子程序使用的VB800-VB900也就是剛才調用子程序所使用的DB塊了,接下來進行詳細說明。



    圖片

    FC第一行Load Data




    圖片

    FC*后一行Save Data




    圖片

    FC中使用DB



    SBR如何知道要使用哪個DB?需要在SBR接口的InOut處設計一個索引參數(DB_Index),這個索引定位了DB。如果該子程序是第一次被執行,索引接口變量就從索引資源變量(IndexSource)處取得當前可以使用的索引,索引資源自加一,以便下個SBR分配索引。如果不是第一次被調用,則不會再分配索引,而是使用原來的索引值,也就定位了同一個DB。

    SBR內已經定位了DB,要怎么使用該DB呢?可以有兩種使用方式:

    一種是復制DB數據到SBR臨時變量區,在Temp區使用的好處是可以用符號變量操作。使用完畢在退出子程序前把同一個Temp內容復制回DB區就實現了猶如在DB區中使用數據一樣的效果。

    第二種使用方式是直接在DB上操作數據,由于并不知道該SBR使用的DB地址,也就不能開始就設計好符號變量(事實上可以開始就設計好符號變量,后面有敘述。),所以直接使用就是用指針操作數據。由于指針操作存在很多不便性,所以這種方式主要用于使用指針顯得很方便的場合,比如數組操作之類。

    隨著背景DB實現程序的設計推進,使用DB的方式這兩種都有采用,針對不同的應用場景有不同的使用方式。比如,如果子程序的Temp區足以容納需要的數據,就使用Temp操作;如果SBR的Temp容量小需要更多的存儲區,就把多余的部分使用直接在DB中操作。如果接口比較多,需要使用更多的接口數量,就使用事先設計好DB中的符號變量,直接操作符號變量的方式,在遵循一定的設計順序后就可以在該方式下也實現多個實例化。

    實現的代價

    要想實現上述功能,犧牲V區的一些空間和增加程序代碼的數量、增加掃描時間是必然的代價,其中,犧牲V區空間其實是談不上的,V區通常足夠大,一般來說不用白不用,用了不白用。*主要的增加了代碼體積和增加了掃描時間。在不增加其他功能,單純一個做好的具有背景DB功能的空白模板,編譯后塊大小是2657字節。

    200Smart的接口數量是有限的,只有16個IO接口,超出限制將不能正常添加形參。有人說可以把多個bit形參組合成Byte、Word、DWord之類,確實有效,但這個不是討論的重點,所謂曲線救國畢竟是曲線呀。要怎么做呢?當然是使用指針了,也就是全局V區作為SBR的形參,可這還是需要人工規劃不同的V區來適用不同的實例,沒有解決根本問題。

    既然已經有了可以自動分配和定位的DB,那么規劃出幾處特殊的DB來作為擴展接口的數據塊。同一種類型的實例使用同一個DB,在DB中事先設計適用于同一個類型的接口變量形參,這樣SBR內部直接使用DB內的變量形參,不用更改。那如何才能適用于同一類型的多個實例呢?我想到了子程序內部使用的Temp變量運行機制。200Smart子程序的臨時變量區其實只有一個,是公共使用的。也有資料表明200Smart的Temp區一共14個,這涉及到200Smart的嵌套層級,這個和我想到的實現無關,只要想到這些就足夠了。

    我的實現方案是設計14個特殊用途的DB,用來作為Temp區使用,命名和子程序內的Temp沖突,但只要知道這個和子程序Temp是不同的概念就可以了。為了區別,以下暫且稱為DBTemp吧。DBTemp的用途一方面是由于SBR內部還是有需要使用全局變量的情況出現無可避免,比如......(想不起來了,大概跟指針反引用有關),如果需要,則把這些數據用某個DBTemp內的預先定義的變量替代,只要使用前后讓這個DBTemp進行FIFO操作,這樣無論SBR何時執行都能夠正確操作。這樣就需要設計DBTemp的FIFO算法。設計14個DBTemp也和之前提到的嵌套有關,其實加入背景數據塊后會降低嵌套深度,因為背景數據塊管理程序需要調用一級子程序,如果需要使用背景DB則留給用戶的嵌套深度是7級主循環嵌套調用。

    考慮到其實實際項目中很少有需要使用全部14層級的情況,所以我安排用*后4個DBTemp作為SBR擴展IO接口。4個也就是只有4類子程序需要擴展接口。之所以是4個,主要是考慮到可能需要擴展的類型有限,使用原來的16個接口就可解決大多數類型的設計,這也是實驗階段目標所導致的,如果需要可以修改少量代碼就可適配。

    使用時首先按照FIFO原則先指定需要使用的DBTemp編號入隊,以保護前面使用者的數據不丟失,然后給DBTemp內的SBR形參賦實際參數值,然后調用SBR。調用完畢處理DBTemp內的需要輸出的參數,*后出隊,恢復前面使用者的數據。這里涉及到接口類型,作為擴展接口的參數全部類同于InOut類型,Out和InOut需要調用完畢及時轉存,而In需要設計者自己保證不會破壞原有數據。

    那么DBTemp每個的容量選擇多少合適呢?我設計了50個字節長度,這個可以在DBInit模塊使用參數進行調整。

    而背景數據塊設計了255個DB可以使用,也是可以在DBInit模塊使用參數進行調整。

    管理模塊的設計

    管理堆表頭設計

    在V中分配的背景DB需要有一些空間來容納管理變量,我把這些變量放置到了開頭,稱作管理DB的表頭。

    這些表頭信息是:

    pHeapHead 指向自身的堆指針,也是Heap首地址。

    HeapStatus 堆狀態信息。

    DBCap 數據塊預置容量

    DBLen 數據塊實際使用長度

    pDBTerminal 數據塊終點地址

    pDBVector 數據塊頭指針

    IndexSource 索引資源

    指定數量的全局數據塊索引

    表頭和DB之間的分隔符"#"

    這些變量的作用涉及到許多技術實現細節,以后慢慢添加。

    之后是數據塊,不過頭兩個DB塊是特殊用途DB的管理塊,本質上這兩個DB和之后的幾個特殊用途DB都是數據塊,只不過由管理程序使用,分配用戶DB也不會用這幾個塊空間來分配。

    1,數據塊的結構

    每個數據塊的第一個字是DB容量,這個由DB分配程序來讀寫,用戶不用操心。
    之后是一個字節的DB標志符"FF",這個是方便調試而設計的,并無多大作用,也是設計遺留下來的東西,唯一的作用是可以幫助分辨DB開始。

    這個標識符唯一不存在于接下來的一個DB。

    然后才是真正的DB數據。

    2,Temp塊管理DB的設計

    Temp塊管理DB管理的其實不只Temp塊,還硬塞進來了FIFO隊列。 FIFO隊列后是14個存放DBTemp的指針向量。DBTemp動態分配,這些指針表在DBTemp初始化時自動生成。由于設計也是逐步推進的,這里采用直接存放4字節的指針,而不是像接下來的用戶DB指針表存放的是V編號,也就是指針的低字數據。

    3,用戶DB指針表(用戶DB管理表)的設計

    用戶DB的定位采用的是遍歷定位方式,但考慮許久還是專門設計出一個DB來存放用戶DB開始的指針數據,這樣DBIndex不是直接定位用戶DB,而是首先定位這個表的數據,然后提取數據作為指針來直接定位用戶DB。好處是代碼量少些,也可能執行起來快速些。

    用戶DB不是一開始就規劃好的,而是動態分配的,位置、尺寸都是動態由子程序自己所需DB尺寸自動生成的。

    4,DBTemp塊的設計

    DBTemp共計14個,每個都具有用戶指定的大小,比如50個字節。沒有內部特殊結構,和普通DB沒有區別。

    用戶可以使用的普通數據塊

    共計255個容量,每個的大小不同,由用戶子程序決定


    聯系方式

    • 電  話:18126392341
    • 聯系人:梁濤
    • 手  機:15267534595
    • 微  信:15267534595