问题解答

C# Modbus TCP通讯实例

C#例程下载:Modbus TCP 连接大连德嘉PLC

这里我只是简单的理解一下Modbus TCP/IP协议的内容,就是去掉了modbus协议本身的CRC校验,增加了MBAP 报文头。这里只是简单的理解,

深入之后可能会有更多的东西需要学习,但为了可以快速入门,我们先按照这个思路往下走。

我们首先来看一下,MBAP 报文头都包括了哪些信息和内容:


下面我们再来介绍一下针对我们PLC的功能码:

1、0x01功能码:按位读取Q区(线圈 )

例:我们来读取从Q0.0到Q0.5这6个线圈

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x01,0x01,0x2A

modbus数据中从左数,0x01表示功能码,0x01表示1个字节数据,0x2A表示数据值,把0x2A转换为2进制为0010 1010,从左数起,前2位

是补充数据00,剩下的101010表示我们读取的Q0.5到Q0.0的状态。

Q0.5------ ON, Q0.4 ------ OFF, Q0.3-------ON,Q0.2--------OFF,Q0.1-------ON,Q0.0----------OFF。

注意数据的顺序,左侧是高位,右侧是低位。

注意:上述发送及接收数据中,红色数码是MBAP报文头,黑色码是modbus数据,下同

2、0x02功能码:按位读取I 区 (离散输入)

例:我们来读取从I0.0到I0.5这6个离散输入点

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x00, 0x00, 0x00, 0x06

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x02,0x01,0x00

modbus数据中从左数,0x02表示功能码,0x01表示1个字节数据,0x00表示数据值,把0x0转换为2进制为0000 0000 , 从左数起,前2位是补充数据00

,剩下的000000表示我们读取的I0.5到I0.0的状态。

3、0x03功能码:按双字节(VW)读取V区或者读MW

Modbus寄存器0-------19999是读取VW,20000------20031是读取MW

例:我们来读取从VW0到VW2这个数据

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x03

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x03,0x06,0x04,0x00,0x03,0x01,0x02,0x05

modbus数据中从左数,0x03表示功能码,0x06表示6个字节数据,0x04,0x00,0x03,0x01,0x02,0x05表示数据值VW0为0x0400,

VW2为0x0301,VW4为0x0205

4、0x05功能码:按位写Q区

例:我们来把Q0.0置1,请注意,置位数据为0xFF00,清零数据为0x0000

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05,0x00,0x00,0xFF,0x00

5、0x06功能码: 按双字节(VW)写V区或者写MW

Modbus寄存器0-------19999是写VW,20000------20031是写MW

例:我们将数据0x2636写入VW0

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x00, 0x26, 0x36

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06,0x00,0x00,0x26,0x36

6、0x0F功能码:按多个位写Q区

例:我们将Q0.0到Q0.5共6个线圈全部置位1

发送码分析:


我们要将Q0.0到Q0.5输出1,要发送的值应该为二进制0011 1111,转换为16进制为 0x3F

根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x0F, 0x00, 0x00, 0x00, 0x06,0x01,0x3F

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x0F,0x00,0x00,0x00,0x06

7、0x10功能码: 写2N个VW 或者MW

Modbus寄存器0-------19999是写VW,20000------20031是写MW

例:我们将数据0x01,0x05,0x0A,0x09写入VW0和VW2

发送码分析:


根据上面的分析,我们需要发送0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x01, 0x10, 0x00, 0x00, 0x00, 0x02,0x04,0x01,0x05,0x0A,0x09

接收码分析:


我们收到的数据为0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10,0x00,0x00,0x00,0x02

至此,我们关于Modbus TCP命令连接我们PLC的分析就结束了,我上传了我做好的C#程序供大家参考,这里要注意一个问题,此程序中缺少

断线重连机制,请大家自己添加一下吧