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