ModbusTCP協議報文解析
報文格式
交互(通信)標識:2個字節 為此次通信事務處理標識符,一般每次通信之后將被要求加1以區別不同的通信數據報文。
協議標識:2個字節 表示該條指令遵循ModbusTCP協議,一般都為00 00
報文長度:2個字節 表示后面數據的長度,有幾個字節,高字節在前
(前六位Modbus/TCP協議不同功能碼通用)
設備標識 :1個字節 設備地址,這個可以用于局域網里面的具體的地址,如果目標機器有固定ip,這個就不起作用,直接上寫成 00
功能碼:1個字節 功能碼在modbus協議用于表示信息幀的功能
數據:N個字節 后面數據根據不同功能碼不同。
modbus 常用功能代碼
十進制 | 功能 | 數據類型 |
---|---|---|
01 | 讀取 多個線圈 | 位 |
02 | 讀取 多個離散量輸入量 | 位 |
03 | 讀取 多個保持寄存器 | 16進制整型 |
04 | 讀取 多個輸入寄存器 | 16進制整型 |
05 | 寫入 單個線圈 | 位 |
06 | 寫入 單個寄存器 | 16進制整型 |
15 | 寫入 多個線圈 | 位 |
16 | 寫入 多個寄存器 | 16進制整型 |
功能碼詳解
01 讀取多個線圈示例報文:
請求:00 01 00 00 00 06 FF 01 00 01 00 10
第1,2位 00 01
交互標識
第3,4位 00 00
協議標識
第5,6位 00 06
后面報文長度 有6位
第7位 FF 設備地址,發送什么,響應什么
第8位 01 功能碼
第9,10位00 01
起始地址
第11,12位 00 10
查詢線圈長度,查詢16位線圈
響應:00 01 00 00 00 05 FF 01 02 0A 02
前四位和7,8位同請求發送的報文
第5,6位是后面報文長度
第9位是后面數據位的長度,
第10位開始是數據位。
01查詢線圈,每一個16進制數據表示8位線圈
第10位0A --> 0000 1010 第二位是1,第四位是1
02 讀取多個離散量輸入同01
03 讀取 多個保持寄存器寄存器讀取與線圈的區別,響應數據,寄存器數據每兩個字節表示1位,一次請求不能超過127個地址
示例報文:
請求:00 01 00 00 00 06 01 03 00 05 00 02
第1,2位 00 01
交互標識
第3,4位 00 00
協議標識
第5,6位 00 06
后面報文長度 有6位
第7位 01
設備地址,發送什么,響應什么
第8位 03
功能碼
第9,10位00 05
起始地址
第11,12位 00 02
查詢寄存器長度,查詢2個寄存器
響應:00 01 00 00 00 07 01 03 04 00 22 00 00
前四位(00 01 00 00
)和7,8位(01 03
)同請求發送的報文
第5,6位 00 07
是后面報文長度
第9位 04 是后面數據位的長度
第10-13位 數據位(00 22 00 00
)
同03
05 (05H)寫入 單個線圈請求:00 01 00 00 00 06 FF 05 00 01 FF 00
第9,10位 00 01
寫入線圈的地址
第11,12位 寫入的數據值 FF 00 表示置ON/1狀態 00 00 表示置OFF/0狀態
響應:00 01 00 00 00 06 FF 05 00 01 FF 00
請求:00 01 00 00 00 06 FF 0F 00 05 00 0A 02 CD 01
第9,10位 00 05
寫入的起始地址
第11,12位 00 0A
寫入線圈數量
第13位 02
數據字節數量
第14位之后是數據 低字節在前
CD 01 —> 1100 1101 0000 0001
位 | 0C | 0B | 0A | 09 | 08 | 07 | 06 | 05 |
值 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
位 | 14 | 13 | 12 | 11 | 10 | 0F | 0E | 0D |
值 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
請求:00 05 00 00 00 06 FF 06 00 05 00 23
向地址為5的寄存器寫入35。
第9,10位 00 05寫入的起始地址
第11,12位 00 0A寫入寄存器的值
響應:00 05 00 00 00 06 FF 06 00 05 00 23
請求:00 06 00 00 00 0B FF 10 00 02 00 02 04 00 21 00 2A
從地址2開始寫入兩個寄存器,2寄存器寫入33,3寄存器寫入42
第9,10位 00 02寫入的起始地址
第11,12位 00 02寫入寄存器的數量
第13位 04 后面數據的字節
第14-17位 數據
響應:00 06 00 00 00 06 FF 10 00 02 00 02
從地址2開始寫入兩個寄存器,2寄存器寫入33,3寄存器寫入42
第9,10位 00 02
寫入的起始地址
第11,12位 00 02
寫入寄存器的數量
第13位 04 后面數據的字節
第14-17位 數據
響應:00 06 00 00 0 0 06 FF 10 00 02 00 02
當發生通訊異常時,響應前7位仍然為modbus正常協議格式,第八位響應功能碼(請求功能碼+0x80),第九位異常碼。
異常數據即包含異常碼的數據:
目前使用的異常碼是:01,02,03和04。
- 響應功能碼 = 請求功能碼 + 0x80
- 響應報文提供異常碼顯示出錯原因。
常見異常碼含義:
異常碼 | 名稱 | 含義 |
---|---|---|
01 | 非法功能 | 對于服務器(或從站)來說,詢問中接收到的功能碼是不可允許的操作,可能是因為功能碼僅適用于新設備而被選單元中不可實現同時,還指出服務器(或從站)在錯誤狀態中處理這種請求,例如:它是未配置的,且要求返回寄存器值。 |
02 | 地址非法 | 對于服務器(或從站)來說,詢問中接收的數據地址是不可允許的地址,特別是參考號和傳輸長度的組合是無效的。對于帶有100個寄存器的控制器來說,偏移量96和長度4的請求會成功,而偏移量96和長度5的請求將產生異常碼02。 |
03 | 數據非法 | 對于服務器(或從站)來說,詢問中包括的值是不可允許的值。該值指示了組合請求剩余結構中的故障。例如:隱含長度是不正確的。modbus協議不知道任何特殊寄存器的任何特殊值的重要意義,寄存器中被提交存儲的數據項有一個應用程序期望之外的值。 |
04 | 從站設備故障 | 當服務器(或從站)正在設法執行請求的操作時,產生不可重新獲得的差錯。 |
float 按IEEE-754標準協議存儲
C#中浮點數的二進制格式遵循IEEE754標準
IEEE-754格式標準:一個浮點數有2部分組成:底數m和指數e
IEEE-754
Modbus協議定義的寄存器地址是5位十進制地址,即:
線圈(DO)地址:00001~09999
觸點(DI)地址:10001~19999
輸入寄存器(AI)地址:30001~39999
輸出寄存器(AO)地址:40001~49999
0x代表線圈(DO)類地址,1x代表觸點(DI)類地址、 3x代表輸入寄存器(AI)類地址、4x代表輸出寄存器(AO)類地址。
在實際編程中,前綴的區分作用(有功能碼進行區分),所以只需說明后4位數,而且需轉換為4位十六進制地址。
Modbus 數據地址格式是從0開始,寄存器地址對應報文中地址關系,x0001
對應00 00
,示例40003
對應 00 02
地址
以上根據開發時查的資料和網上資料整理一些的有用信息,方便開發查詢