在Modbus RTU消息中編輯浮點數(實數)和32位數據
豆腐包子 2019-09-04 13:29:56 1551 收藏 2
展開
目錄
字節順序的重要性
確定字節順序
實際幫助
在使用Modbus RTU協議時常常會遇到要傳輸32位浮點型數據的情況。本文討論如何解決傳輸浮點數的問題。
點對點的Modbus協議時RTU通信的常用選擇。協議本身控制Modbus網絡上每個設備的交互,設備如何建立已知地址,每個設備如何識別其消息以及如何從數據中提取基本信息。從本質上講,該協議是整個Modbus網絡的基礎。
然而,這種便利並非沒有一些復雜性,Modbus RTU消息協議也不例外。協議本身是基於具有16位寄存器長度的器件設計的。因此,在實現32位數據元素時需要特別注意。該實現決定使用兩個連續的16位寄存器來表示32位數據或基本4字節的數據。在這4個字節的數據中,單精度浮點數據可以編碼為Modbus RTU消息。
字節順序的重要性
Modbus本身沒有定義浮點數據類型,但人們普遍認為它使用IEEE-754標准實現了32位浮點數據。但是,IEEE標准沒有明確規定數據有效載荷的字節順序。因此,處理32位數據時最重要的考慮因素是數據按正確順序尋址。
例如,IEEE 754單精度32位浮點數標准中定義的數字123456.00如下所示:
各種字節排序的影響很大。例如,在“B A D C”序列中對表示123456.00的4字節數據進行排序,稱為“字節交換”。當解釋為IEEE 744浮點數據類型時,結果完全不同:
在“C D A B”序列中排序相同的字節稱為“字交換”。同樣,結果與原始值123456.00大不相同:
此外,“字節交換”和“字交換”基本上都會完全顛倒字節序列以產生另一個結果:
顯然,在使用Modbus等網絡協議時,必須嚴格注意內存字節在傳輸時的排序方式,也稱為“字節順序”。
確定字節順序
根據Modbus應用協議規范V1.1.b,Modbus協議本身被聲明為“big-Endian”協議:
“Modbus uses a “big-Endian” representation for addresses and data items. This means that when a numerical quantity larger than a single byte is transmitted, the most significant byte is sent first.”
Big-Endian是網絡協議最常用的格式 - 實際上很常見,它也被稱為“網絡秩序”。
鑒於Modbus RTU消息協議是big-Endian,為了通過Modbus RTU消息成功交換32位數據類型,必須考慮主站和從站的字節順序。許多RTU主設備和從設備允許特定的字節順序選擇,特別是在軟件模擬單元的情況下。必須確保所有單元都設置為相同的字節順序。
根據經驗,設備的微處理器系列決定了它的字節順序。通常,big-Endian樣式(首先存儲高位字節,然后是低位字節)通常在使用Motorola處理器設計的CPU中找到。 little-Endian樣式(首先存儲低位字節,然后是高位字節)通常在使用Intel架構的CPU中找到。關於哪種風格被認為是“倒退”,這是個人觀點的問題。
但是,如果字節順序和字節順序不是可配置選項,則必須確定如何解釋字節。這可以通過從從站請求已知的浮點值來完成。如果返回不可能的值,即具有兩位數指數等的數字,則字節排序很可能需要修改。
實際幫助
FieldServer Modbus RTU驅動程序提供多種功能移動,可處理32位整數和32位浮點值。更重要的是,這些函數移動考慮了所有不同形式的字節排序。下表顯示了FieldServer函數移動,它將兩個相鄰的16位寄存器復制為32位整數值。
Function Keyword Swap Mode Source Bytes Target Bytes
2.i16-1.i32 N/A [ a b ] [ c d ] [ a b c d ]
2.i16-1.i32-s byte and word swap [ a b ] [ c d ] [ d c b a ]
2.i16-1.i32-sb byte swap [ a b ] [ c d ] [ b a d c ]
2.i16-1.i32-sw word swap [ a b ] [ c d ] [ c d a b ]
下表顯示了FieldServer函數移動,它將兩個相鄰的16位寄存器復制到32位浮點值:
Function Keyword Swap Mode Source Bytes Target Bytes
2.i16-1.ifloat N/A [ a b ] [ c d ] [ a b c d ]
2.i16-1.ifloat-s byte and word swap [ a b ] [ c d ] [ d c b a ]
2.i16-1.ifloat-sb byte swap [ a b ] [ c d ] [ b a d c ]
2.i16-1.ifloat-sw word swap [ a b ] [ c d ] [ c d a b ]
下表顯示了FieldServer函數移動,它將單個32位浮點值復制到兩個相鄰的16位寄存器:
Function Keyword Swap Mode Source Bytes Target Bytes
1.float-2.i16 N/A [ a b c d ] [ a b ][ c d ]
1.float-2.i16-s byte and word swap [ a b c d ] [ a b ][ c d ]
1.float-2.i16-sb byte swap [ a b c d ] [ a b ][ c d ]
1.float-2.i16-sw word swap [ a b c d ] [ a b ][ c d ]
鑒於FieldServer函數的移動,32位數據的正確處理取決於選擇合適的數據。觀察這些FieldServer函數的以下行為在已知的單精度十進制浮點值123456.00上移動:
16-bit Values Function Move Result Function Move Result
0x2000 0x47F1 2.i16-1.float 123456.00 1.float-2.i16 0x2000 0x47F1
0xF147 0x0020 2.i16-1.float-s 123456.00 1.float-2.i16-s 0xF147 0X0020
0x0020 0xF147 2.i16-1.float-sb 123456.00 1.float-2.i16-sb 0x0020 0xF147
0x47F1 0x2000 2.i16-1.float-sw 123456.00 1.float-2.i16-sw 0x47F1 0x2000
請注意,不同的字節和字順序需要使用相應的FieldServer函數移動。選擇正確的功能移動后,可以在兩個方向上轉換數據。
在互聯網上可用的許多十六進制到浮點轉換器和計算器中,很少有實際允許操作字節和字順序。一個這樣的實用程序可以在這里下載。該實用程序的十進制浮點值為123456.00,如下所示:
然后可以交換字節和/或字來分析Modbus RTU主設備和從設備之間可能存在的潛在字節序問題。
————————————————
版權聲明:本文為CSDN博主「豆腐包子」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/m0_37827925/article/details/100532669