一、Modbus TCP數據幀
ModbusTCP的數據幀可分為兩部分:MBAP+PDU。

在 TCP/IP 上使用一種專用報文頭識別 MODBUS 應用數據單元。將這種報文頭稱為 MBAP 報文頭(MODBUS 協議報文頭)。這種報文頭提供一些與串行鏈路上使用的 MODBUS RTU 應用數據單元比較的差別 :
- 用 MBAP 報文頭中的單個字節單元標識符取代 MODBUS 串行鏈路上通常使用的 MODBUS從地址域。這個單元標識符用於設備的通信,這些設備使用單個IP地址支持多個獨立Modbus終端單元,例如:網橋、路由器和網關。
- 用接收者可以驗證完成報文的方式設計所有 MODBUS 請求和響應。對於 MODBUS PDU有固定長度的功能碼來說,僅功能碼就足夠了。對於在請求或響應中攜帶一個可變數據的功能碼來說,數據域包括字節數。
- 當在 TCP 上攜帶 MODBUS 時,即使將報文分成多個信息包來傳輸,辦事在 MBAP 報文頭上攜帶附加長度信息,以便接收者能識別報文邊界。顯式和隱式長度規則的存在以及CRC-32 差錯校驗碼的使用(在以太網上)將對請求或響應報文產生極小的未檢出干擾。
二、MBAP報文頭
原文鏈接:https://www.cnblogs.com/ioufev/articles/10830028.html
MBAP的長度為7個字節,組成如下:
| 事務處理標識 | 協議標識 | 長度 | 單元標識符 |
|---|---|---|---|
| 2字節 | 2字節 | 2字節 | 1字節 |
| 內容 | 解釋 |
|---|---|
| 事務處理標識 | 可以理解為報文的序列號,一般每次通信之后就要加1以區別不同的通信數據報文。 |
| 協議標識符 | 00 00表示ModbusTCP協議。 |
| 長度 | 表示接下來的數據長度,單位為字節。 |
| 單元標識符 | 可以理解為設備地址。 |
四、幀結構PDU
PDU由功能碼+數據組成。功能碼為1字節,數據長度不定,由具體功能決定。
功能碼
Modbus的操作對象有四種:線圈、離散輸入、輸入寄存器、保持寄存器。
| 對象 | 含義 |
|---|---|
| 線圈 | PLC的輸出位,開關量,在Modbus中可讀可寫 |
| 離散量 | PLC的輸入位,開關量,在Modbus中只讀 |
| 輸入寄存器 | PLC中只能從模擬量輸入端改變的寄存器,在Modbus中只讀 |
| 保持寄存器 | PLC中用於輸出模擬量信號的寄存器,在Modbus中可讀可寫 |
根據對象的不同,常用的Modbus的功能碼有:
| 功能碼 | 含義 |
|---|---|
| 0x01 | 讀線圈 |
| 0x05 | 寫單個線圈 |
| 0x0F | 寫多個線圈 |
| 0x02 | 讀離散量輸入 |
| 0x04 | 讀輸入寄存器 |
| 0x03 | 讀保持寄存器 |
| 0x06 | 寫單個保持寄存器 |
| 0x10 | 寫多個保持寄存器 |
0x01:讀線圈
在從站中讀1~2000個連續線圈狀態,ON=1,OFF=0
- 請求:MBAP 功能碼 起始地址H 起始地址L 數量H 數量L(共12字節)
- 響應:MBAP 功能碼 數據長度 數據(一個地址的數據為1位)
- 如:在從站0x01中,讀取開始地址為0x0002的線圈數據,讀0x0008位
00 01 00 00 00 06 01 01 00 02 00 08 - 回:數據長度為0x01個字節,數據為0x01,第一個線圈為ON,其余為OFF
00 01 00 00 00 04 01 01 01 01
0x05:寫單個線圈
將從站中的一個輸出寫成ON或OFF,0xFF00請求輸出為ON,0x000請求輸出為OFF
- 請求:MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節)
- 響應:MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節)
- 如:將地址為0x0003的線圈設為ON
00 01 00 00 00 06 01 05 00 03 FF 00 - 回:寫入成功
00 01 00 00 00 06 01 05 00 03 FF 00
0x0F:寫多個線圈
將一個從站中的一個線圈序列的每個線圈都強制為ON或OFF,數據域中置1的位請求相應輸出位ON,置0的位請求響應輸出為OFF
- 請求:MBAP 功能碼 起始地址H 起始地址L 輸出數量H 輸出數量L 字節長度 輸出值H 輸出值L
- 響應:MBAP 功能碼 起始地址H 起始地址L 輸出數量H 輸出數量L
0x02:讀離散量輸入
從一個從站中讀1~2000個連續的離散量輸入狀態
- 請求:MBAP 功能碼 起始地址H 起始地址L 數量H 數量L(共12字節)
- 響應:MBAP 功能碼 數據長度 數據(長度:9+ceil(數量/8))
- 如:從地址0x0000開始讀0x0012個離散量輸入
00 01 00 00 00 06 01 02 00 00 00 12 - 回:數據長度為0x03個字節,數據為0x01 04 00,表示第一個離散量輸入和第11個離散量輸入為ON,其余為OFF
00 01 00 00 00 06 01 02 03 01 04 00
0x04:讀輸入寄存器
從一個遠程設備中讀1~2000個連續輸入寄存器
- 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
- 響應:MBAP 功能碼 數據長度 寄存器數據(長度:9+寄存器數量×2)
- 如:讀起始地址為0x0002,數量為0x0005的寄存器數據
00 01 00 00 00 06 01 04 00 02 00 05 - 回:數據長度為0x0A,第一個寄存器的數據為0x0c,其余為0x00
00 01 00 00 00 0D 01 04 0A 00 0C 00 00 00 00 00 00 00 00
0x03:讀保持寄存器
從遠程設備中讀保持寄存器連續塊的內容
- 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
- 響應:MBAP 功能碼 數據長度 寄存器數據(長度:9+寄存器數量×2)
- 如:起始地址是0x0000,寄存器數量是 0x0003
00 01 00 00 00 06 01 03 00 00 00 03 - 回:數據長度為0x06,第一個寄存器的數據為0x21,其余為0x00
00 01 00 00 00 09 01 03 06 00 21 00 00 00 00
0x06:寫單個保持寄存器
在一個遠程設備中寫一個保持寄存器
- 請求:MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節)
- 響應:MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節)
- 如:向地址是0x0000的寄存器寫入數據0x000A
00 01 00 00 00 06 01 06 00 00 00 0A - 回:寫入成功
00 01 00 00 00 06 01 06 00 00 00 0A
0x10:寫多個保持寄存器
在一個遠程設備中寫連續寄存器塊(1~123個寄存器)
- 請求:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L 字節長度 寄存器值(13+寄存器數量×2)
- 響應:MBAP 功能碼 起始地址H 起始地址L 寄存器數量H 寄存器數量L(共12字節)
- 如:向起始地址為0x0000,數量為0x0001的寄存器寫入數據,數據長度為0x02,數據為0x000F
00 01 00 00 00 09 01 10 00 00 00 01 02 00 0 - 回:寫入成功
00 01 00 00 00 06 01 10 00 00 00 01
五、Modbus TCP示例報文
ModBusTcp與串行鏈路Modbus的數據域是一致的,具體數據域可以參考串行Modbus。這里給出幾個ModbusTcp的鏈路解析說明,輔助新人分析報文。
原文鏈接:https://blog.csdn.net/mikasoi/article/details/81782159
1、數據請求
| 97 76 00 00 00 06 04 04 00 7D 00 7D |
||||
|
|
示例 |
長度 |
說明 |
備注 |
| Map報文頭 |
0x97 |
1 |
事務處理標識符Hi |
客戶機發起,服務器復制,用於事務處理配對 |
| 0x96 |
1 |
事務處理標識符Lo |
||
| 0x0000 |
2 |
協議標識符號 |
客戶機發起,服務器復制 Modbus協議 = 0. |
|
| 0x0006 |
2 |
長度 |
從本字節下一個到最后
|
|
| 0x04 |
1 |
單元標識符 |
客戶機發起,服務器復制 串口鏈路或其他總線上遠程終端標識 |
|
| 功能碼 |
0x04 |
1 |
功能碼,讀寄存器 |
參考標准modbus協議 |
| 數據 |
0x007D |
2 |
起始地址 |
|
| 0x 007D |
2 |
寄存器數量 |
|
|
| 校驗 |
|
|||
2、數據請求回復
| 97 76 00 00 00 FD 04 04 FA AB 9E 41 18 7A E1 3F 94 7A E1 3F 94 0A 3D 3F 97 51 EC 3F 98 CC CD C0 6C 33 33 C0 E3 CC CD C0 EC EB 85 41 F1 D7 0A 41 E9 47 AE 41 ED EB 85 41 F1 19 9A 43 D0 E6 66 43 C9 4C CD 43 CF EB 85 41 F3 66 66 42 0F CC CD 41 C2 E6 66 44 0A 1E B8 41 FB A3 D7 42 0C CC CD 41 BC C0 00 44 0A B8 52 41 F6 5C 29 42 0F 47 AE 41 D1 C6 66 44 0A 00 00 00 00 C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F C9 9E FF 7F 05 16 00 00 04 11 00 00 05 16 00 00 04 11 00 00 05 16 00 00 04 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A 00 0A 00 0A 00 0A 00 04 00 04 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0F |
||||
|
|
示例 |
長度 |
說明 |
備注 |
| Map報文頭 |
0x97 |
1 |
事務處理標識符Hi |
客戶機發起,服務器復制,用於事務處理配對 |
| 0x96 |
1 |
事務處理標識符Lo |
||
| 0x0000 |
2 |
協議標識符號 |
客戶機發起,服務器復制 Modbus協議 = 0. |
|
| 0x00FD |
2 |
長度 |
從本字節下一個到最后
|
|
| 0x04 |
1 |
單元標識符 |
客戶機發起,服務器復制 串口鏈路或其他總線上遠程終端標識 |
|
| 功能碼 |
0x04 |
1 |
功能碼,讀寄存器 |
參考標准modbus協議 |
| 數據 |
0x FA |
1 |
字節個數 |
|
| 0x---- |
|
數據 |
||
| 校驗 |
|
|||
3、寫多個寄存器
| 97 79 00 00 00 09 04 10 00 00 00 01 02 00 01 |
||||
|
|
示例 |
長度 |
說明 |
備注 |
| Map報文頭 |
0x97 |
1 |
事務處理標識符Hi |
客戶機發起,服務器復制,用於事務處理配對 |
| 0x79 |
1 |
事務處理標識符Lo |
||
| 0x0000 |
2 |
協議標識符號 |
客戶機發起,服務器復制 Modbus協議 = 0. |
|
| 0x0009 |
2 |
長度 |
從本字節下一個到最后
|
|
| 0x04 |
1 |
單元標識符 |
客戶機發起,服務器復制 串口鏈路或其他總線上遠程終端標識 |
|
| 功能碼 |
0x10 |
1 |
功能碼,讀寄存器 |
參考標准modbus協議 |
| 數據 |
0x0000 |
2 |
起始地址 |
|
| 0x 0001 |
2 |
寫寄存器數量 |
|
|
| 0x 02 |
1 |
寫字節的個數 |
|
|
| 00 01 |
2 |
目標值 |
|
|
| 校驗 |
|
|||
4、寫多個寄存器響應
| 97 79 00 00 00 06 04 10 00 00 00 01 |
||||
|
|
示例 |
長度 |
說明 |
備注 |
| Map報文頭 |
0x97 |
1 |
事務處理標識符Hi |
客戶機發起,服務器復制,用於事務處理配對 |
| 0x79 |
1 |
事務處理標識符Lo |
||
| 0x0000 |
2 |
協議標識符號 |
客戶機發起,服務器復制 Modbus協議 = 0. |
|
| 0x0006 |
2 |
長度 |
從本字節下一個到最后
|
|
| 0x04 |
1 |
單元標識符 |
客戶機發起,服務器復制 串口鏈路或其他總線上遠程終端標識 |
|
| 功能碼 |
0x10 |
1 |
功能碼,讀寄存器 |
參考標准modbus協議 |
| 數據 |
0x0000 |
2 |
起始地址 |
|
| 0x 0001 |
2 |
寄存器個數 |
|
|
| 校驗 |
|
|||
