說(shuō)明 VARIANT 數(shù)據(jù)類(lèi)型的參數(shù)是一個(gè)指針或引用,,可指向各種不同數(shù)據(jù)類(lèi)型的變量,。VARIANT 指針無(wú)法指向?qū)嵗虼瞬荒苤赶蚨嘀貙?shí)例或多重實(shí)例的 ARRAY,。VARIANT 指針可以是基本數(shù)據(jù)類(lèi)型(例如,,INT 或 REAL)的對(duì)象。還可以是 STRING,、DTL,、STRUCT 類(lèi)型的 ARRAY,、UDT、UDT 類(lèi)型的 ARRAY,。VARIANT 指針可以識(shí)別結(jié)構(gòu),,并指向各個(gè)結(jié)構(gòu)元素。VARIANT 數(shù)據(jù)類(lèi)型的操作數(shù)不占用背景數(shù)據(jù)塊或工作存儲(chǔ)器中的空間,。但是,,將占用 CPU 上的存儲(chǔ)空間。 VARIANT 類(lèi)型的變量不是一個(gè)對(duì)象,,而是對(duì)另一個(gè)對(duì)象的引用,。在函數(shù)的塊接口中的 VAR_IN、VAR_IN_OUT 和 VAR_TEMP 部分中,,VARIANT 類(lèi)型的單個(gè)元素只能聲明為形參,。因此,不能在數(shù)據(jù)塊或函數(shù)塊的塊接口靜態(tài)部分中聲明,,例如,,因?yàn)楦髟氐拇笮∥粗K脤?duì)象的大小可以更改,。 使用 VARIANT 數(shù)據(jù)類(lèi)型時(shí),,可為各種數(shù)據(jù)類(lèi)型創(chuàng)建通用的標(biāo)準(zhǔn)函數(shù)塊 (FB) 或函數(shù) (FC)。為此,,可使用所有編程語(yǔ)言中的各種指令,。在程序創(chuàng)建過(guò)程中,可指定該塊可處理數(shù)據(jù)類(lèi)型,。在此,,可使用 VARIANT 數(shù)據(jù)類(lèi)型對(duì)各種變量進(jìn)行互連。之后,,再根據(jù)這些變量在塊中的數(shù)據(jù)類(lèi)型進(jìn)行響應(yīng),。調(diào)用某個(gè)塊時(shí),,可以將該塊的參數(shù)連接到任何數(shù)據(jù)類(lèi)型的變量,。調(diào)用某個(gè)塊時(shí),除了傳遞變量的指針外,,還會(huì)傳遞變量的類(lèi)型信息,。塊代碼隨后可以根據(jù)運(yùn)行期間傳遞的變量類(lèi)型來(lái)執(zhí)行。 例如,,如果函數(shù)的塊參數(shù)為 VARIANT 數(shù)據(jù)類(lèi)型,,那么整數(shù)數(shù)據(jù)類(lèi)型的變量可以在程序中的一個(gè)點(diǎn)處傳遞,而 PLC 數(shù)據(jù)類(lèi)型的變量可以在程序中的另一個(gè)點(diǎn)處傳遞,。借助 VARIANT 指令,,函數(shù)隨后可以正確響應(yīng)這種情況,而不會(huì)出錯(cuò)。 說(shuō)明 如果一個(gè)數(shù)據(jù)塊最初的數(shù)據(jù)類(lèi)型為用戶自定義的數(shù)據(jù)類(lèi)型 (UDT),,那么只能指向完整的數(shù)據(jù)塊,。 |
說(shuō)明 訪問(wèn) I/O 只有 S7-1500 模塊的 CPU 才能直接讀寫(xiě) I/O 輸出或輸出中的信號(hào)。(<操作數(shù)>:P) |
下表列出了 VARIANT 指針的屬性: 長(zhǎng)度(字節(jié)) | 表示法 | 格式 | 輸入值示例 | 0 | 符號(hào) | 操作數(shù) | 'TagResult' | 數(shù)據(jù)塊名稱(chēng).操作數(shù)名稱(chēng).元素 | 'Data_TIA_Portal'.StructVariable.FirstComponent | 絕對(duì) | 操作數(shù) | %MW10 | 數(shù)據(jù)塊編號(hào).操作數(shù) 類(lèi)型長(zhǎng)度 | P#DB10.DBX10.0 INT 12 1) | NULL 指針 | NULL | 1) 如果使用前綴 P#,,則只能指向“標(biāo)準(zhǔn)”訪問(wèn)模式的存儲(chǔ)區(qū),。 |
數(shù)據(jù)類(lèi)型的編碼 如果通過(guò) P# 使用絕對(duì)尋址,則允許使用以下數(shù)據(jù)類(lèi)型: - BOOL
- BYTE
- CHAR
- WORD
- INT
- DWORD
- DINT
- REAL
- TIME
- S5TIME
- DATE
- TOD
- DT
示例 以下示例說(shuō)明了 VARIANT 使用 STL 指令“MOVE:移動(dòng)值”的工作原理: STL | 說(shuō)明 | CALL MOVE | // 調(diào)用指令,。 | value_type := VARIANT | // 參數(shù) IN 和 OUT 的數(shù)據(jù)類(lèi)型 | IN := 'Data_TIA_Portal'.StructVariable.FirstComponent | // 從“Data_TIA_Portal”數(shù)據(jù)塊移動(dòng)操作數(shù)“FirstComponent”中的數(shù)據(jù),。 | OUT := 'MotorDB'.StructResult.TagResult | // 從“MotorDB”數(shù)據(jù)塊傳送到“TagResult”操作數(shù)中。 |
S7-1200/1500 CPU 中的指針用例(與 S7-300/400 相比) 下表簡(jiǎn)要列出了 S7-300/400 系列 CPU(ANY 指針)與 S7-1200/1500 系列 CPU 中指針的各種應(yīng)用及解決方案,。 在大多數(shù)應(yīng)用中,,S7-1200/1500 系列 CPU 無(wú)需使用指針。取而代之的是更為簡(jiǎn)單的語(yǔ)言資源,。 在程序運(yùn)行時(shí)期間只需確定數(shù)據(jù)類(lèi)型時(shí),,才建議使用 VARIANT 數(shù)據(jù)類(lèi)型進(jìn)行間接尋址。 ANY 指針的用途 | 在 TIA Portal 中應(yīng)用時(shí)的建議 (S7-1200/S7-1500) | 使用指令“BLKMOV:塊移動(dòng)”,,在程序中移動(dòng)任意源和目標(biāo)數(shù)據(jù)類(lèi)型的數(shù)據(jù),。 | 在 PLC 數(shù)據(jù)類(lèi)型中變量定義。使用指令“Serialize”和“Deserialize”,,移動(dòng)變量,。 | 初始化 ARRAY 結(jié)構(gòu) | 使用指令“FILL_BLK:填充塊”,初始化或填充 ARRAY 結(jié)構(gòu),。 | 移動(dòng) ARRAY 元素 | 使用指令“MOVE_BLK:塊移動(dòng)”,,將一個(gè) ARRAY 結(jié)構(gòu)中的多個(gè)元素內(nèi)容移到另一個(gè) ARRAY 結(jié)構(gòu)中。 | 使用結(jié)構(gòu)化數(shù)據(jù),,優(yōu)化存儲(chǔ)器和性能 | 使用塊接口中的 InOut 部分優(yōu)化存儲(chǔ)器和性能,。 更新信息,敬請(qǐng)?jiān)L問(wèn)“S7-1200/1500 編程指南”中的《S7-1200/1500 編程指南》 | 訪問(wèn) WORD 的各個(gè)位/字節(jié) | 使用“片段訪問(wèn)” 更多信息,,請(qǐng)參見(jiàn)“片段訪問(wèn)示例” | 確定結(jié)構(gòu)或數(shù)據(jù)塊的長(zhǎng)度 | 使用 ARRAY 并讀取其長(zhǎng)度:使用指令“CountofElements:獲取 ARRAY 元素個(gè)數(shù)”,。該指令只能與數(shù)據(jù)類(lèi)型 VARIANT 結(jié)合使用。 | 間接尋址 | 使用 VARIANT 指針,,可對(duì)僅在運(yùn)行過(guò)程中已知的數(shù)據(jù)類(lèi)型進(jìn)行間接尋址,。使用數(shù)據(jù)類(lèi)型 DB_ANY,可對(duì)數(shù)據(jù)塊進(jìn)行間接訪問(wèn),。 |
VARIANT 指令 TIA Portal 中提供了以下用于處理 VARIANT 的指令: 基本指令 | 類(lèi)別 | 指令 | 說(shuō)明 | 比較器運(yùn)算 | EQ_Type | 比較數(shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“相等” | NE_Type | 比較數(shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“不相等” | EQ_ElemType | 比較 ARRAY 元素?cái)?shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“相等” | NE_ElemType | 比較 ARRAY 元素?cái)?shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“不相等” | IS_NULL | EQUALS ZERO 指針查詢 | NOT_NULL | UNEQUALS ZERO 指針查詢 | IS_ARRAY | 檢查 ARRAY | TypeOf | 檢查 VARIANT 變量的數(shù)據(jù)類(lèi)型 | TypeOfElements | 檢查 VARIANT 變量的元素?cái)?shù)據(jù)類(lèi)型 | 移動(dòng)操作 | MOVE_BLK_VARIANT | 塊移動(dòng) | VariantGet | 讀取 VARIANT 變量值 | VariantPut | 寫(xiě)入 VARIANT 變量值 | CountOfElements | 獲取 ARRAY 元素個(gè)數(shù) | 轉(zhuǎn)換操作 | VARIANT_TO_DB_ANY | 將 VARIANT 轉(zhuǎn)換為 DB_ANY | DB_ANY_TO_VARIANT | 將 DB_ANY 轉(zhuǎn)換為 VARIANT |
說(shuō)明 MOVE,、MOVE_BLK 和 MOVE_BLK_VARIANT 之間的區(qū)別 - 可使用“MOVE”指令來(lái)復(fù)制完整的結(jié)構(gòu)。
- 可使用“MOVE_BLK”指令來(lái)移動(dòng)具有已知數(shù)據(jù)類(lèi)型的 ARRAY 的部分,。
- 僅在您想要移動(dòng)其數(shù)據(jù)類(lèi)型僅在程序運(yùn)行時(shí)期間已知的 ARRAY 的部分時(shí),,才需要使用 MOVE_BLK_VARIANT 指令,。
|
可以在信息系統(tǒng)的“基本指令 > 對(duì)應(yīng)編程語(yǔ)言”(Basic instructions > Respective programming language) 下找到有關(guān)各種指令的其它信息。 也可以在“擴(kuò)展指令”(Extended instructions) 下找到同樣用于處理 VARIANT 數(shù)據(jù)類(lèi)型的其它指令,。 簡(jiǎn)介 在下一章中,,您將了解可用于 VARIANT 指令的應(yīng)用選項(xiàng)。 對(duì) VARIANT 指向的變量的數(shù)據(jù)類(lèi)型求值 在下表中,,您將看到可使用哪些指令來(lái)對(duì) VARIANT 指向的變量的數(shù)據(jù)類(lèi)型求值: 函數(shù) | 指令 | 說(shuō)明 | 確定數(shù)據(jù)類(lèi)型 | TypeOf():檢查 VARIANT 變量的數(shù)據(jù)類(lèi)型 (該指令僅適用于 SCL,,且只能與 IF 或 CASE 指令一起使用。) | 可使用該指令將 VARIANT 變量指向的數(shù)據(jù)類(lèi)型與任何其它變量的數(shù)據(jù)類(lèi)型進(jìn)行比較,。也可以與 PLC 數(shù)據(jù)類(lèi)型作比較,。 | TypeOfElements():掃描 VARIANT 變量 ARRAY 元素的數(shù)據(jù)類(lèi)型 (該指令僅適用于 SCL,且只能與 IF 或 CASE 指令一起使用,。) | 可使用該指令將 VARIANT 變量指向的數(shù)據(jù)類(lèi)型與任何其它變量的數(shù)據(jù)類(lèi)型進(jìn)行比較,。也可以與 PLC 數(shù)據(jù)類(lèi)型作比較。如果 VARIANT 變量的數(shù)據(jù)類(lèi)型為 ARRAY,,則將比較 ARRAY 元素的數(shù)據(jù)類(lèi)型,。 | EQ_Type:比較數(shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“相等” NE_Type:比較數(shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“不相等” | 可使用該指令將 VARIANT 變量指向的數(shù)據(jù)類(lèi)型與任何其它變量的數(shù)據(jù)類(lèi)型進(jìn)行比較。也可以與 PLC 數(shù)據(jù)類(lèi)型作比較,。 | EQ_ElemType:比較 ARRAY 元素?cái)?shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“相等” NE_ElemType:比較 ARRAY 元素?cái)?shù)據(jù)類(lèi)型與變量數(shù)據(jù)類(lèi)型是否“不相等” | 可使用該指令將 VARIANT 變量指向的數(shù)據(jù)類(lèi)型與任何其它變量的數(shù)據(jù)類(lèi)型進(jìn)行比較,。也可以與 PLC 數(shù)據(jù)類(lèi)型作比較。如果 VARIANT 變量的數(shù)據(jù)類(lèi)型為 ARRAY,,則將比較 ARRAY 元素的數(shù)據(jù)類(lèi)型,。 | 對(duì) ARRAY 元素求值 | IS_ARRAY:檢查 ARRAY | 可使用該指令檢查 VARIANT 變量指向的數(shù)據(jù)類(lèi)型是否為 ARRAY。 | CountOfElements:獲取 ARRAY 元素個(gè)數(shù) | 可使用該指令讀出該變量中 VARIANT 變量指向了多少個(gè) ARRAY 元素,。 |
可以在信息系統(tǒng)的“基本指令 > 對(duì)應(yīng)編程語(yǔ)言”(Basic instructions > Respective programming language) 下找到有關(guān)各種指令的其它信息,。 讀取 VARIANT 指向的數(shù)據(jù) 為了能夠使用數(shù)據(jù),您必須在一個(gè)中間步驟中將該數(shù)據(jù)移到變量中,,因?yàn)闊o(wú)法直接處理該數(shù)據(jù),。 指令 | 說(shuō)明 | 示例 | 結(jié)果 | VARIANT 指向 | 目標(biāo)數(shù)據(jù)類(lèi)型 | VariantGet:讀取 VARIANT 變量值 | 可使用該指令將單個(gè)變量的值移到另一個(gè)變量中。這兩個(gè)變量的數(shù)據(jù)類(lèi)型必須匹配,。 | UDT_1 | UDT_1 | 已執(zhí)行該指令,。 | REAL | REAL | DINT | DWORD | 該指令未執(zhí)行。 |
將數(shù)據(jù)分配給 VARIANT 變量 無(wú)法使用該指令來(lái)初始化 VARIANT 變量,。因此,,在將數(shù)據(jù)返回到變量時(shí)必須已經(jīng)初始化 VARIANT 變量。請(qǐng)勿使用未初始化的臨時(shí) VARIANT 變量,。 指令 | 說(shuō)明 | 示例 | 結(jié)果 | 源數(shù)據(jù)類(lèi)型 | VARIANT 指向: | VariantPut:寫(xiě)入 VARIANT 變量值 | 可使用該指令將單個(gè)變量的值移到另一個(gè)變量中。這兩個(gè)變量的數(shù)據(jù)類(lèi)型必須匹配,。 | UDT_1 | UDT_1 | 已執(zhí)行該指令,。 | REAL | REAL | DINT | DWORD | 將不執(zhí)行該指令,,因?yàn)閿?shù)據(jù)類(lèi)型不同。 |
處理動(dòng)態(tài) ARRAY 結(jié)構(gòu) 對(duì) ARRAY 元素求值 | TypeOfElements():掃描 VARIANT 變量 ARRAY 元素的數(shù)據(jù)類(lèi)型 (該指令僅適用于 SCL,,且只能與 IF 或 CASE 指令一起使用,。) | 可使用該指令將 VARIANT 變量指向的數(shù)據(jù)類(lèi)型與任何其它變量的數(shù)據(jù)類(lèi)型進(jìn)行比較。也可以與 PLC 數(shù)據(jù)類(lèi)型作比較,。如果 VARIANT 變量的數(shù)據(jù)類(lèi)型為 ARRAY,,則將比較 ARRAY 元素的數(shù)據(jù)類(lèi)型。 | IS_ARRAY:檢查 ARRAY | 可使用該指令檢查 VARIANT 變量指向的數(shù)據(jù)類(lèi)型是否為 ARRAY,。 | CountOfElements:獲取 ARRAY 元素個(gè)數(shù) | 可使用該指令讀出該變量中 VARIANT 變量指向了多少個(gè) ARRAY 元素,。 | MOVE_BLK_VARIANT:塊移動(dòng) | 可使用該指令移動(dòng)動(dòng)態(tài)和類(lèi)型安全(集成類(lèi)型測(cè)試)ARRAY??梢詾樵春湍繕?biāo) ARRAY 自由選擇限值,。ARRAY 元素的數(shù)據(jù)類(lèi)型必須匹配。 |
說(shuō)明 MOVE,、MOVE_BLK 和 MOVE_BLK_VARIANT 之間的區(qū)別 - 可使用“MOVE”指令來(lái)復(fù)制完整的結(jié)構(gòu),。
- 可使用“MOVE_BLK”指令來(lái)移動(dòng)具有已知數(shù)據(jù)類(lèi)型的 ARRAY 的部分。
- 僅在您想要移動(dòng)其數(shù)據(jù)類(lèi)型僅在程序運(yùn)行時(shí)期間已知的 ARRAY 的部分時(shí),,才需要使用 MOVE_BLK_VARIANT 指令,。
|
可以在“移動(dòng)數(shù)據(jù)”(Moving data) 編程示例中找到有關(guān)使用 MOVE_BLK_VARIANT 指令的其它信息。 說(shuō)明 通過(guò)在塊調(diào)用時(shí)為 VARIANT 塊參數(shù)指定一個(gè)特定變量,,對(duì) VARIANT 數(shù)據(jù)類(lèi)型進(jìn)行初始化,。這將形成對(duì)所傳遞變量地址的引用。為此,,需在塊接口中創(chuàng)建一個(gè) VARIANT 數(shù)據(jù)類(lèi)型的塊參數(shù),。在以下示例中,在 SourceArray 部分中包含兩個(gè)塊參數(shù) DestinationArray 和 InOut,。 該示例顯示了“移動(dòng)數(shù)據(jù)示例”中的部分編程示例,。詳細(xì)的程序代碼,請(qǐng)參見(jiàn)“另請(qǐng)參見(jiàn)”,。 說(shuō)明 系統(tǒng)不支持將變量直接傳遞到 VARIANT 變量中,。如,myVARIANT: = #Variable |
使用 VARIANT 傳遞和讀取各種數(shù)據(jù)類(lèi)型 | |
該示例顯示了“移動(dòng)數(shù)據(jù)示例”中的部分編程示例,。詳細(xì)的程序代碼,,請(qǐng)參見(jiàn)“另請(qǐng)參見(jiàn)”。 說(shuō)明 VARIANT 作為形參 如果將 VARIANT 聲明為一個(gè)形參,,則未寫(xiě)保護(hù)的數(shù)據(jù)將作為實(shí)參進(jìn)行傳遞,。 |
傳遞各種數(shù)據(jù)類(lèi)型 在以下示例中,將顯示多次調(diào)用通用的標(biāo)準(zhǔn)函數(shù)時(shí)如何使用不同變量對(duì) VARIANT 塊參數(shù)進(jìn)行初始化: “FC_PartialArrayCopy”函數(shù)將調(diào)用兩次,。通過(guò)左側(cè)的調(diào)用,,將 VARIANT 參數(shù) SourceArray 與“my_struct”數(shù)據(jù)類(lèi)型的 ARRAY 互連,。通過(guò)右側(cè)的調(diào)用,將 VARIANT 參數(shù) SourceArray 與 REAL 數(shù)據(jù)類(lèi)型的 ARRAY 互連,。 讀出并檢查數(shù)據(jù)類(lèi)型 系統(tǒng)目前支持各種不同的比較指令,,可讀取變量或元素的數(shù)據(jù)類(lèi)型,并將其與其它變量或元素的數(shù)據(jù)類(lèi)型進(jìn)行比較,。 在下圖中,,將顯示如何使用多個(gè)比較指令檢查 ARRAY 的元素是否具有相同的數(shù)據(jù)類(lèi)型: 僅當(dāng) ARRAY 元素的數(shù)據(jù)類(lèi)型相同時(shí),才執(zhí)行 MOVE_BLK_VARIANT 指令,。 編程示例 在此編程示例中,,將移動(dòng)在生產(chǎn)班次期間為示例收集的數(shù)據(jù)值以作進(jìn)一步處理。 收集的數(shù)據(jù)放在 ARRAY 中,。 通過(guò)“MOVE_BLK_VARIANT: 移動(dòng)塊”(Move block) 指令,,可以動(dòng)態(tài)或以類(lèi)型安全方式移動(dòng)整個(gè) ARRAY 或個(gè)別 ARRAY 元素。 可以為源和目標(biāo) ARRAY 自由選擇 ARRAY 限值,,這些限值不必匹配,。 但是,要移動(dòng)的數(shù)據(jù)值的數(shù)據(jù)類(lèi)型必須匹配,。 該指令在所有編程語(yǔ)言中都可用,。 通過(guò) VARIANT 數(shù)據(jù)類(lèi)型,也可以使用已創(chuàng)建的程序代碼并通過(guò)在塊調(diào)用中指定不同的源和目標(biāo)區(qū)域來(lái)移動(dòng)另一個(gè)生產(chǎn)班次的數(shù)據(jù),。 步驟 - 使用 SCL 編程語(yǔ)言創(chuàng)建函數(shù)并將其命名為“FC_PartialArrayCopy”,。
- 按如下方式聲明塊接口:
3.按如下方式創(chuàng)建 SCL 程序代碼:可以找到以下程序代碼作為模板。 4.創(chuàng)建 PLC 數(shù)據(jù)類(lèi)型“UDT_MyStruct”: 5.創(chuàng)建全局?jǐn)?shù)據(jù)塊“DB_WithArrays”:
6.在組織塊(例如 OB1)中調(diào)用“FC_PartialArrayCopy”函數(shù),,并使用 DB_WithArrays 數(shù)據(jù)塊初始化參數(shù),。 輸入指定的常量: 7.也可以使用第三個(gè)和第四個(gè) ARRAY(數(shù)據(jù)類(lèi)型為 REAL)來(lái)代替使用前兩個(gè) ARRAY (數(shù)據(jù)類(lèi)型為 UDT_MyStruct)。 結(jié)果 在程序周期中調(diào)用“FC_PartialArrayCopy”塊后,,會(huì)將從第四個(gè)元素開(kāi)始的兩個(gè)數(shù)據(jù)值立即從“DB_WithArrays”全局?jǐn)?shù)據(jù)塊的第一個(gè) ARRAY 復(fù)制到該數(shù)據(jù)塊的第二個(gè) ARRAY 中,。 復(fù)制的數(shù)據(jù)值將插入到第二個(gè) ARRAY 中(從第四個(gè)元素開(kāi)始)。 用于復(fù)制的 SCL 程序代碼: SCL | IF IS_ARRAY(#SourceArray) AND TypeOfElements(#SourceArray) = TypeOfElements(#DestinationArray) THEN | #Error := MOVE_BLK_VARIANT(COUNT := #Count, SRC := #SourceArray, SRC_INDEX := #SourceIndex, | DEST => #DestinationArray, DEST_INDEX := #DestinationIndex); | END_IF; | #FC_PartialArrayCopy := #Error; |
編程示例 在以下示例中,,您編寫(xiě)了一個(gè)環(huán)形緩沖區(qū),,該緩沖區(qū)包含一個(gè) ARRAY,并且根據(jù) FIFO 原理進(jìn)行讀寫(xiě),。該程序代碼有一個(gè)讀取 VARIANT 指針和一個(gè)寫(xiě)入 VARIANT 指針,。通過(guò) VARIANT 指令,可以編寫(xiě)穩(wěn)定的程序代碼并確??煽康剡M(jìn)行復(fù)制或刪除,。 通過(guò) VARIANT 數(shù)據(jù)類(lèi)型,程序部分在運(yùn)行時(shí)期間可能會(huì)受影響。VARIANT 指針是類(lèi)型安全指針,,即在運(yùn)行時(shí)期間執(zhí)行類(lèi)型測(cè)試,。對(duì)于使用塊屬性“optimized”創(chuàng)建的塊,,先前使用 ANY 指針編寫(xiě)的子函數(shù)現(xiàn)在可以使用 VARIANT 指針進(jìn)行解析,。可使用 VARIANT 數(shù)據(jù)類(lèi)型將結(jié)構(gòu)傳送到系統(tǒng)函數(shù)塊,。 步驟 - 創(chuàng)建 SCL 函數(shù)塊并將其命名為“FIFOQueue”,。
- 按如下方式聲明塊接口:
- 聲明
- 參數(shù)
- 數(shù)據(jù)類(lèi)型
- 注釋
- Input
- request
- BOOL
- 當(dāng)“request”參數(shù)中檢測(cè)到信號(hào)上升沿時(shí),將執(zhí)行該指令,。
- mode
- BOOL
- 0 = 返回環(huán)形緩沖區(qū)的第一個(gè)條目,。
- 1 = 條目被寫(xiě)入環(huán)形緩沖區(qū)的最后一個(gè)位置。
- initialValue
- VARIANT
- 環(huán)形緩沖區(qū)的 ARRAY 被初始化的值,。
- Output
- error
- INT
- 錯(cuò)誤信息
- InOut
- item
- VARIANT
- 從環(huán)形緩沖區(qū)中返回或?qū)懭氲江h(huán)形緩沖區(qū)的條目,。
- buffer
- VARIANT
- 用于環(huán)形緩沖區(qū)的 ARRAY。
- Static
- edgeupm
- BOOL
- 保存上一次查詢的 RLO 的邊沿存儲(chǔ)位,。
- firstItemIndex
- INT
- 環(huán)形緩沖區(qū)中最舊條目的索引
- nextEmptyItemIndex
- INT
- 環(huán)形緩沖區(qū)中下一個(gè)空閑條目的索引
- Temp
- edgeup
- BOOL
- 邊沿檢測(cè)的結(jié)果
- internalError
- INT
- 錯(cuò)誤信息
- newFirstItemIndex
- INT
- 可變下標(biāo)
- newNextEmptyItemIndex
- INT
- 可變下標(biāo)
- bufferSize
- UDINT
- 環(huán)形緩沖區(qū)中 ARRAY 元素的數(shù)量
- 在“FIFOQueue”函數(shù)塊中創(chuàng)建以下程序代碼:
| (* 該程序代碼部分僅在信號(hào)上升沿后執(zhí)行一次,。如果邏輯運(yùn)算結(jié)果的信號(hào)狀態(tài)沒(méi)有改變,則將“FIFOQueue”FB 的程序執(zhí)行將終止,。 *) | #edgeup := #request & NOT #edgeupm; | #edgeupm := #request; | IF NOT (#edgeup) THEN | RETURN; | END_IF; | | | // ------驗(yàn)證所有參數(shù)輸入是否均有效,。---- | (* 該程序代碼部分檢查環(huán)形緩沖區(qū)是否為 ARRAY。如果是的話,,將讀取 ARRAY 元素的數(shù)量,。如果不是 ARRAY,程序執(zhí)行將在該點(diǎn)終止,,并輸出錯(cuò)誤代碼“-10”,。*) | IF NOT (IS_ARRAY(#buffer)) THEN | #error := -10; | RETURN; | ELSE | #bufferSize := CountofElements(#buffer); | END_IF; | | (* 該程序代碼部分將檢查 ARRAY 元素的數(shù)據(jù)類(lèi)型是否匹配條目的數(shù)據(jù)類(lèi)型(變量 #項(xiàng)目)。如果數(shù)據(jù)類(lèi)型不匹配,,則程序執(zhí)行將在該點(diǎn)終止,,并輸出錯(cuò)誤代碼“-11”。*) | IF NOT (TypeOf(#item) = TypeOfElements(#buffer)) THEN | #error := -11; | RETURN; | END_IF; | | (* 該程序代碼部分將檢查環(huán)形緩沖區(qū)的初始值是否匹配條目(變量 #項(xiàng)目),。如果數(shù)據(jù)類(lèi)型不匹配,,則程序執(zhí)行將在該點(diǎn)終止,并輸出錯(cuò)誤代碼“-12”,。*) | IF NOT (TypeOf(#item) = TypeOf(#initialValue)) THEN | #error := -12; | RETURN; | END_IF; | | (* 該程序代碼部分將檢查變量索引是否在 ARRAY 限值之內(nèi),。如果不是,程序執(zhí)行將在該點(diǎn)終止,,并且輸出錯(cuò)誤代碼“-20”或“-21”,,具體取決于索引。*) | IF (#nextEmptyItemIndex >= #bufferSize) THEN | #error := -20; | RETURN; | END_IF; | IF (#firstItemIndex >= #bufferSize) THEN | #error := -21; | RETURN; | END_IF; | | | //-----------程序代碼執(zhí)行,具體取決于模式參數(shù)------------- | // 指令的執(zhí)行取決于模式參數(shù)的信號(hào)狀態(tài),。 | IF #mode = 0 THEN | | // 如果模式參數(shù)的信號(hào)狀態(tài)為“0”,,將返回傳遞的環(huán)形緩沖區(qū)的第一個(gè)條目。 | (* 該程序代碼部分檢查環(huán)形緩沖區(qū)是否為空,。如果是,,程序執(zhí)行將在該點(diǎn)終止,并輸出錯(cuò)誤代碼“-40”,。*) | IF (#firstItemIndex = -1) THEN | #error := -40; | RETURN; | END_IF; | | // 該程序代碼部分將返回環(huán)形緩沖區(qū)的第一個(gè)條目,。 | #internalError := MOVE_BLK_VARIANT(SRC := #buffer, | COUNT := 1, | SRC_INDEX := #firstItemIndex, | DEST_INDEX := 0, | DEST => #item); | | IF (#internalError = 0) THEN | (* 該程序代碼部分檢查環(huán)形緩沖區(qū)是否包含 ARRAY 元素。如果是,,則傳遞第一個(gè)條目,,且索引遞增 1。*) | #internalError := MOVE_BLK_VARIANT(SRC := #initialValue, | COUNT := 1, | SRC_INDEX := 0, | DEST_INDEX := #firstItemIndex, | DEST => #buffer); | | // 該程序代碼部分將計(jì)算第一個(gè)條目的新索引,。 | #newFirstItemIndex := #firstItemIndex +1; | #newFirstItemIndex := #newFirstItemIndex MOD UDINT_TO_INT(#bufferSize); | | // 該程序部分將檢查環(huán)形緩沖區(qū)是否為空,。 | IF (#nextEmptyItemIndex = #newFirstItemIndex) THEN | // 如果環(huán)形緩沖區(qū)為空,索引將被設(shè)置為 0,。 | #firstItemIndex := -1; | #nextEmptyItemIndex := 0; | ELSE | // 第一個(gè)條目的索引已更改,。 | #firstItemIndex := #newFirstItemIndex; | END_IF; | END_IF; | ELSE | | | // 如果模式參數(shù)的信號(hào)狀態(tài)為“1”,條目將寫(xiě)入到傳遞的環(huán)形緩沖區(qū)中,。 | (* 該程序代碼部分檢查環(huán)形緩沖區(qū)是否已滿,。如果是,程序執(zhí)行將在該點(diǎn)終止,,并輸出錯(cuò)誤代碼“-50”,。*) | IF (#nextEmptyItemIndex = #firstItemIndex) THEN | #error := -50; | RETURN; | END_IF; | | // 該程序代碼部分會(huì)將條目寫(xiě)入環(huán)形緩沖區(qū)中。 | #internalError := MOVE_BLK_VARIANT(SRC := #item, | COUNT := 1, | SRC_INDEX := 0, | DEST_INDEX := #nextEmptyItemIndex, | DEST => #buffer); | | IF (#internalError = 0) THEN | // 該程序代碼部分會(huì)使索引加 1,,并計(jì)算新的空條目索引,。 | #newNextEmptyItemIndex := #nextEmptyItemIndex +1; | #newNextEmptyItemIndex := #newNextEmptyItemIndex MOD #bufferSize; | #nextEmptyItemIndex := #newNextEmptyItemIndex; | | (* 該程序代碼部分會(huì)檢查“#firstItemIndex”變量有哪些索引。如果數(shù)字為 -1,,環(huán)形緩沖區(qū)將初始化,,條目將寫(xiě)入到環(huán)形緩沖區(qū)中。這也正是必須為變量分配“0”的原因所在,。*) | IF (#firstItemIndex = -1) THEN | #firstItemIndex := 0; | END_IF; | END_IF; | END_IF; | | //-------------------------局部錯(cuò)誤處理 ----------------------------
| (* 該程序代碼部分將檢查是否出現(xiàn)局部錯(cuò)誤,。如果是,程序執(zhí)行將在該點(diǎn)終止,,并輸出錯(cuò)誤代碼“-100”,。*) | IF (#internalError > 0) THEN | #error := -100; | RETURN; | END_IF; | | // 如果在程序執(zhí)行期間沒(méi)有出錯(cuò),將輸出錯(cuò)誤代碼“0”,。 | #error := 0; |
結(jié)果在程序中運(yùn)行 FIFO 隊(duì)列的位置調(diào)用 SCL 函數(shù)塊,。
|