Python的網絡編程[6] -> Modbus 協議 -> Modbus 的基本理論與 Python 實現


Modbus協議 / Modbus Protocol


目錄

  1. Modbus 協議簡介
  2. Modbus RTU協議
  3. Modbus TCP協議與 Python 實現
  4. Modbus 功能碼
  5. Modbus TCP/RTU對比

 

1 Modbus 協議簡介

Modbus協議MODICON公司1979年開發的一種通信協議,是一種工業現場總線協議標准,1996年施耐德公司推出了基於以太網TCP/IP的Modbus協議—ModbusTCP。

Modbus協議是一項應用層報文傳輸協議,包括ASCII / RTU / TCP三種報文類型,協議本身不定義物理層,只定義了控制器能夠認識和使用的消息結構,而不管消息是經過何種網絡進行通信的。

標准的Modbus協議物理層接口主要有RS232 / RS422 / RS485和以太網。采用Master/Slave主從方式通信。

 

2 Modbus RTU協議 / Modbus RTU Protocol

Modbus RTU協議報文格式主要如下,

名稱              字節數   位號       描述

------------       ---------   ------      ------

設備地址   1            1           

功能碼       1         2            03H讀寄存器/06H寫單個寄存器/10H寫多個寄存器

寄存器地址  2            3-4         高位在前

數據長度         2            5-6         傳送數據總長度

CRC校驗         2            7-8        

 下面是不同操作時使用的報文格式

 

3 Modbus TCP協議 / Modbus TCP Protocol

3.1 Modbus TCP協議格式

Modbus TCP協議報文格式主要可分為兩段,MBAP和PDU,

MBAP:

名稱              字節數   位號       描述

------------      ---------   ------       ------

事物標識符   2            1-2         由服務器復制返回,通常為\x00\x00

協議表示符   2      3-4         通常為\x00\x00

數據長度       2         5-6         傳送數據總長度,高位通常\x00(數據不超過256),低位為后續字節長度

單元標識符   1         7            通常為\x00

PDU:

名稱              字節數   位號       描述

------------      ---------   ------       ------

功能碼           1            8            定義功能

起始寄存器   2         9-10       操作的寄存器起始位

寄存器/數據  2         11-12     讀/多個寫模式下,為寄存器數量,單個寫模式為寫入數據

3.2 Modbus TCP 加解碼的 Python 實現 / Modbus TCP Encode and Decode by Python

 1 import struct
 2 
 3 
 4 class ModbusCodeC():
 5     """
 6     This CodeC class implement partly of Modbus encode and decode
 7     The chamber only offer 03H and 06H function-code for using
 8     """
 9 
10     @staticmethod
11     def MBAP_encode():
12         transFlagHi = b'\x00'
13         transFlagLo = b'\x00'
14         protoFlag = b'\x00\x00'
15         length = b'\x00\x06'
16         unitFlag = b'\x00'
17         mbap = transFlagHi + transFlagLo + protoFlag + length + unitFlag
18         return mbap
19 
20     @staticmethod
21     def PDU_encode(func, regi, num=1, data=None):
22         funcList = {'r': b'\x03',
23                     'w': b'\x06'}
24         funcCode = funcList[func]
25         registerStart = struct.pack('!H', regi)
26         registerNum = struct.pack('!H', num)
27         if data and func == 'w':
28             dataCode = struct.pack('!H', data)
29             pdu = funcCode + registerStart + dataCode
30             return pdu
31         pdu = funcCode + registerStart + registerNum
32         return pdu
33 
34     @staticmethod
35     def encode(func, regi, num, data=None):
36         return ModbusCodeC.MBAP_encode() + ModbusCodeC.PDU_encode(func, regi, num, data)
37 
38     @staticmethod
39     def MBAP_decode(s):
40         m = {}
41         m['transFlagHi'] = s[:1]
42         m['transFlagLo'] = s[1:2]
43         m['protoFlag'] = s[2:4]
44         m['length'] = s[4:6]
45         m['unitFlag'] = s[6:]
46         return m
47         
48     @staticmethod
49     def PDU_decode(s):
50         p = {}
51         '''
52         p['funcCode'] = s[:1]
53         p['registerStart'] = s[1:3]
54         p['registerNum'] = s[3:5]
55         p['data'] = s[5:]
56         '''
57         # TODO: Add bit number and data length check here
58         p['funcCode'] = s[:1]
59         p['bitNum'] = s[1:2]
60         p['data'] = s[2:]
61         return p
62 
63     @staticmethod
64     def decode(msg):
65         msg_de = {}
66         mbap, pdu = msg[:7], msg[7:]
67         msg_de['MBAP'] = ModbusCodeC.MBAP_decode(mbap)
68         msg_de['PDU'] = ModbusCodeC.PDU_decode(pdu)
69         return msg_de
70 
71 if __name__ == '__main__':
72     print(ModbusCodeC.encode('r', 5, 3))
73     print(ModbusCodeC.encode('w', 5, 1, 8))

4 Modbus 功能碼/ Modbus Function Code

在Modbus功能碼中,1-65位為公共功能碼,定義了一些通用的功能

5 Modbus TCP/RTU對比 / Modbus TCP/RTU Comparison

5.1 Modbus RTUModbus TCP讀指令對比

 

MBAP報文頭

地址碼

功能碼

寄存器地址

寄存器數量

CRC校驗

Modbus   RTU

01

03

01   8E

00   04

25   DE

Modbus   TCP

00   00 00 00 00 06 00

03

01   8E

00   04

指令的涵義:從地址碼為01(TCP協議單元標志為00)的模塊0x18E(01 8E)寄存器地址開始讀(03)四個(00 04)寄存器。

5.2 Modbus RTUModbus TCP寫指令對比

 

MBAP報文頭

地址碼

功能碼

寄存器地址

寄存器數量

數據長度

正文

CRC校驗

RTU

01

10

01   8E

00   01

02

00   00

A8   7E

TCP

00   00 00 00 00 09 00

10

01   8E

00   01

02

00   00

指令的涵義:從地址碼為01(TCP協議單元標志為00)的模塊0x18E(01 8E)寄存器地址開始寫(10)一個(00 01)寄存器,具體數據長度為2個字節(02),數據正文內容為00 00(00 00)。

參考鏈接


http://blog.csdn.net/yangbingzhou/article/details/39504015

http://www.485-can-tcp.com/technology/232485/Modbus.htm

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM