做內(nèi)貿(mào)只要有什么網(wǎng)絡(luò)推廣網(wǎng)站搜索引擎技術(shù)基礎(chǔ)
MODBUS TCP協(xié)議實例數(shù)據(jù)幀詳細分析
1.簡介
2.ModbusTCP數(shù)據(jù)幀
2.1.報文頭MBAP
2.2.幀結(jié)構(gòu)PDU
3.ADU詳細結(jié)構(gòu)
3.1. 0x01:讀線圈
3.2. 0x02:讀離散量輸入
3.3. 0x03:讀保持寄存器
3.4. 0x04:讀輸入寄存器
3.5. 0x05:寫單個線圈
3.6. 0x06:寫單個保持寄存器
3.7. 0x0F:寫多個線圈
3.8. 0x10:寫多個保持寄存器
1.簡介
Modbus由MODICON公司于1979年開發(fā),是一種工業(yè)現(xiàn)場總線協(xié)議標準。1996年施耐德公司推出基于以太網(wǎng)TCP/IP的Modbus協(xié)議:ModbusTCP。Modbus協(xié)議是一項應(yīng)用層報文傳輸協(xié)議,包括ASCII、RTU、TCP三種報文類型。標準的Modbus協(xié)議物理層接口有RS232、RS422、RS485和以太網(wǎng)接口,采用master/slave方式通信。
2.ModbusTCP數(shù)據(jù)幀
ModbusTCP的數(shù)據(jù)幀可分為兩部分:MBAP+PDU,如下圖所示。
2.1.報文頭MBAP
MBAP為報文頭,長度為7字節(jié),組成如下:
事務(wù)處理標識?? ?協(xié)議標識?? ?長度?? ?單元標識符
2字節(jié)?? ?2字節(jié)?? ?2字節(jié)?? ?1字節(jié)
內(nèi)容?? ?含義
事務(wù)處理標識?? ?可以理解為報文的序列號,一般每次通信之后就要加1以區(qū)別不同的通信數(shù)據(jù)報文
協(xié)議標識符?? ?00 00 表示Modbus TCP協(xié)議
長度?? ?表示接下來的數(shù)據(jù)長度,單位為字節(jié)。
單元標識符?? ?可以理解為設(shè)備地址
2.2.幀結(jié)構(gòu)PDU
PDU由功能碼+數(shù)據(jù)組成。功能碼為1字節(jié),數(shù)據(jù)長度不定,由具體功能決定。
Modbus的操作對象有四種:線圈、離散輸入、保持寄存器、輸入寄存器。
對象?? ?含義
線圈?? ?PLC的輸出位,開關(guān)量,在Modbus中可讀可寫
離散量?? ?PLC的輸入位,開關(guān)量,在Modbus中只讀
輸入寄存器?? ?PLC中只能從模擬量輸入端改變的寄存器,在Modbus中只讀
保持寄存器?? ?PLC中用于輸出模擬量信號的寄存器,在Modbus中可讀可寫
根據(jù)對象的不同,Modbus的功能碼有:?? ?
功能碼?? ?含義
–?? ?–
0x01?? ?讀線圈
0x02?? ?讀離散量輸入
0x03?? ?讀保持寄存器
0x04?? ?讀輸入寄存器
0x05?? ?寫單個線圈
0x06?? ?寫單個保持寄存器
0x0F?? ?寫多個線圈
0x10?? ?寫多個保持寄存器
說明更詳細的表如下表所示?? ?
功能碼?? ?中文含義解析
–?? ?–
0x01?? ?讀線圈狀態(tài)
0x02?? ?讀離散量輸入狀態(tài)
0x03?? ?讀保持寄存器
0x04?? ?讀輸入寄存器
0x05?? ?寫單個線圈
0x06?? ?寫單個保持寄存器
0x0F?? ?寫多個線圈
0x10?? ?寫多個保持寄存器
3.ADU詳細結(jié)構(gòu)
3.1. 0x01:讀線圈
在從站中讀連續(xù)線圈狀態(tài),ON=1,OFF=0。
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?線圈數(shù)量H?? ?線圈數(shù)量L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?線圈數(shù)據(jù)長度?? ?數(shù)據(jù)
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?線圈數(shù)據(jù)長度個字節(jié)
注意:線圈數(shù)據(jù)長度=1+(線圈數(shù)-1)/8
如:在從站0x01中,讀取開始地址為0x0000的線圈數(shù)據(jù),讀0x0008位。
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?線圈數(shù)量H?? ?線圈數(shù)量L
00 01 00 00 00 06 01?? ?01?? ?00?? ?00?? ?00?? ?08
如:數(shù)據(jù)長度為0x01個字節(jié),數(shù)據(jù)為0x01,第一個線圈為ON,其余為OFF。
響應(yīng):
MBAP?? ?功能碼?? ?線圈數(shù)據(jù)長度?? ?數(shù)據(jù)
00 01 00 00 00 04 01?? ?01?? ?01?? ?01
3.2. 0x02:讀離散量輸入
在從站中讀連續(xù)離散量輸入狀態(tài),ON=1,OFF=0。
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?離散量輸入數(shù)量H?? ?離散量輸入數(shù)量L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?離散量輸入數(shù)據(jù)長度?? ?數(shù)據(jù)
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?離散量輸入數(shù)據(jù)長度個字節(jié)
注意:離散量輸入數(shù)據(jù)長度=1+(離散量輸入-1)/8
如:在從站0x01中,讀取開始地址為0x0000的線圈數(shù)據(jù),讀0x0008位。
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?離散量輸入數(shù)量H?? ?離散量輸入數(shù)量L
00 01 00 00 00 06 01?? ?02?? ?00?? ?00?? ?00?? ?08
如:在從站0x01中,讀取開始地址為0x0000的離散量輸入數(shù)據(jù),讀0x008位
響應(yīng):
MBAP?? ?功能碼?? ?離散量輸入數(shù)據(jù)長度?? ?數(shù)據(jù)
00 01 00 00 00 04 01?? ?02?? ?01?? ?01
3.3. 0x03:讀保持寄存器
在從站中讀連續(xù)保持寄存器的值
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?寄存器數(shù)量H?? ?寄存器數(shù)量L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?數(shù)據(jù)長度?? ?數(shù)據(jù)
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?數(shù)據(jù)長度個字節(jié)
注意:保持寄存器數(shù)據(jù)長度=保持寄存器數(shù)*2
如:在從站0x01中,讀取開始地址為0x0000的保持寄存器數(shù)據(jù),讀0x003個
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?寄存器數(shù)量H?? ?寄存器數(shù)量L
00 01 00 00 00 06 01?? ?03?? ?00?? ?00?? ?00?? ?03
如:數(shù)據(jù)長度為0x06個字節(jié),第1個寄存器的數(shù)據(jù)為0x21,其余為0x00。
響應(yīng):
MBAP?? ?功能碼?? ?數(shù)據(jù)長度?? ?數(shù)據(jù)
00 01 00 00 00 09 01?? ?03?? ?06?? ?00 21 00 00 00 00
3.4. 0x04:讀輸入寄存器
在從站中讀連續(xù)輸入寄存器的值
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?寄存器數(shù)量H?? ?寄存器數(shù)量L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?數(shù)據(jù)長度?? ?數(shù)據(jù)
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?數(shù)據(jù)長度個字節(jié)
注意:輸入寄存器數(shù)據(jù)長度=輸入寄存器數(shù)*2
如:在從站0x01中,讀取開始地址為0x0000的輸入寄存器數(shù)據(jù),讀0x003個
請求:
MBAP?? ?功能碼?? ?起始地址H?? ?起始地址L?? ?寄存器數(shù)量H?? ?寄存器數(shù)量L
00 01 00 00 00 06 01?? ?04?? ?00?? ?00?? ?00?? ?03
如:數(shù)據(jù)長度為0x06個字節(jié),第1個寄存器的數(shù)據(jù)為0x21,其余為0x00。
響應(yīng):
MBAP?? ?功能碼?? ?數(shù)據(jù)長度?? ?數(shù)據(jù)
00 01 00 00 00 09 01?? ?04?? ?06?? ?00 21 00 00 00 00
3.5. 0x05:寫單個線圈
將從站中的一個線圈輸出寫成ON或OFF,0xFF00請求輸出為ON,0x000請求輸出為OFF
請求:
MBAP?? ?功能碼?? ?線圈地址H?? ?線圈地址L?? ?輸出值H?? ?輸出值L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?線圈地址H?? ?線圈地址L?? ?輸出值H?? ?輸出值L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
如:在從站0x01中,將地址為0x0000的線圈設(shè)置為ON
請求:
MBAP?? ?功能碼?? ?線圈地址H?? ?線圈地址L?? ?輸出值H?? ?輸出值L
00 01 00 00 00 06 01?? ?05?? ?00?? ?00?? ?FF?? ?00
響應(yīng):
MBAP?? ?功能碼?? ?線圈地址H?? ?線圈地址L?? ?輸出值H?? ?輸出值L
00 01 00 00 00 06 01?? ?05?? ?00?? ?00?? ?FF?? ?00
3.6. 0x06:寫單個保持寄存器
將從站中的一個保持寄存器設(shè)置
請求:
MBAP?? ?功能碼?? ?保持寄存器地址H?? ?保持寄存器地址L?? ?設(shè)置值H?? ?設(shè)置值L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
響應(yīng):
MBAP?? ?功能碼?? ?保持寄存器地址H?? ?保持寄存器地址L?? ?設(shè)置值H?? ?設(shè)置值L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
如:在從站0x01中,將地址為0x0000的保持寄存器設(shè)置為0x000A。
請求:
MBAP?? ?功能碼?? ?保持寄存器地址H?? ?保持寄存器地址L?? ?設(shè)置值H?? ?設(shè)置值L
00 01 00 00 00 06 01?? ?06?? ?00?? ?00?? ?00?? ?0A
響應(yīng):
MBAP?? ?功能碼?? ?保持寄存器地址H?? ?保持寄存器地址L?? ?設(shè)置值H?? ?設(shè)置值L
00 01 00 00 00 06 01?? ?06?? ?00?? ?00?? ?00?? ?0A
3.7. 0x0F:寫多個線圈
將從站中的多個線圈輸出寫成ON或OFF,線圈輸出值每1位“1”請求輸出為ON,“0”請求輸出為OFF
請求:
MBAP?? ?功能碼?? ?線圈起始地址H?? ?線圈起始地址L?? ?線圈數(shù)H?? ?線圈數(shù)L?? ?線圈輸出字節(jié)長度?? ?線圈輸出值
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
注意:線圈輸出字節(jié)長度=1+(線圈數(shù)-1)/8
響應(yīng):
MBAP?? ?功能碼?? ?線圈起始地址H?? ?線圈起始地址L?? ?線圈數(shù)H?? ?線圈數(shù)L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
如:在從站0x01中,將以地址0x0000開始連續(xù)的4個線圈設(shè)置為ON
請求:
MBAP?? ?功能碼?? ?線圈起始地址H?? ?線圈起始地址L?? ?線圈數(shù)H?? ?線圈數(shù)L?? ?線圈輸出字節(jié)長度?? ?線圈輸出值
00 01 00 00 00 08 01?? ?0F?? ?00?? ?00?? ?00?? ?04?? ?01?? ?0F
響應(yīng):
MBAP?? ?功能碼?? ?線圈起始地址H?? ?線圈起始地址L?? ?線圈數(shù)H?? ?線圈數(shù)L
00 01 00 00 00 06 01?? ?0F?? ?00?? ?00?? ?00?? ?04
3.8. 0x10:寫多個保持寄存器
寫從站中的多個連續(xù)的寄存器。
請求:
MBAP?? ?功能碼?? ?寄存器起始地址H?? ?寄存器起始地址L?? ?寄存器數(shù)H?? ?寄存器數(shù)L?? ?寄存器數(shù)據(jù)字節(jié)長度?? ?寄存器數(shù)據(jù)
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
注意:寄存器數(shù)據(jù)字節(jié)長度=寄存器數(shù)量×2
響應(yīng):
MBAP?? ?功能碼?? ?寄存器起始地址H?? ?寄存器起始地址L?? ?寄存器數(shù)H?? ?寄存器數(shù)L
7字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)?? ?1字節(jié)
如:在從站0x01中,向起始地址為0x0000,數(shù)量為0x0001的寄存器寫入數(shù)據(jù),數(shù)據(jù)長度為0x02,數(shù)據(jù)為0x000F。
請求:
MBAP?? ?功能碼?? ?寄存器起始地址H?? ?寄存器起始地址L?? ?寄存器數(shù)H?? ?寄存器數(shù)L?? ?寄存器數(shù)據(jù)字節(jié)長度?? ?寄存器數(shù)據(jù)
00 01 00 00 00 09 01?? ?10?? ?00?? ?00?? ?00?? ?01?? ?02?? ?00 0F
響應(yīng):
MBAP?? ?功能碼?? ?寄存器起始地址H?? ?寄存器起始地址L?? ?寄存器數(shù)H?? ?寄存器數(shù)L
00 01 00 00 00 06 01?? ?10?? ?00?? ?00?? ?00?? ?01