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

 

转载于:https://www.cnblogs.com/stacklike/p/8149941.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值