目录
一 测试环境配置:
二 MODBUS概述:
三 MODBUS测试步骤:
四 MODBUS协议分析:
一 测试环境配置:
本文用到的测试工具如下:
(1)Mthings:MThings是一款基于MODBUS协议簇,面向开发、测试、运维人员的辅助工具。支持模拟主机和模拟从机两种模式。
二 MODBUS概述:
Modbus是一种单主站的主/从通信模式。Modbus网络上只能有一个主站存在,主站在 Modbus网络上没有地址,从站的地址范围为 0 - 247,其中 0 为广播地址,从站的实际地址范围为 1 - 247。 Modbus通信标准协议可以通过各种传输方式传播,如 RS232C、RS485、光纤、无线电等。
Modbus具有两种串行传输模式,ASCII 和 RTU。它们定义了数据如何打包、解码的不同方式。支持 Modbus 协议的设备一般都支持 RTU 格式。通信双方必须同时支持上述模式中的一种。
三 MODBUS测试步骤:
总体思路就是通过VSPD虚拟串口工具,虚拟化出两个PC本地串口,再将两个串口虚拟连接(告别硬件连接),这样得到一堆连接着的串口。再通过Mthings工具,将COM1仿真为MODBUS主机,将COM2仿真为MODBUS从机,这样完成MODBUS的主从通讯。
(1)【虚拟串口】:
通过VSPD虚拟串口工具,虚拟化出两个PC本地串口,再将两个串口虚拟连接(告别硬件连接):
(2)【连接配置】:
打开Mthings,列表中显示COM1与COM2,根据需要进行参数配置和设备操作(设置主/从),这边将COM1设为主机,COM2设为从机:
(3)【数据配置】:
选中操作的设备,左上角选择“数据”,进入配置态。这边新增两种数据:
一种命名为“电压”,一种命名为“电流”,其他的属性根据需要进行选择,我这边仅修改了一下字节序(数值大小退出配置模式才能设置):
设置完成之后,同步到主机,这样,主机中也有电压和电流的数据配置了(我这边为了后面测试MODBUS的0x10批量写功能,额外在主机的配置模式中,将批量写进行了勾选):
至此,主机与从机的MODBUS数据配置完毕,下面来进行测试。
(4)【功能测试】:
勾选右上角“报文”,这样就可以对收发报文进行分析。
【1】测试主机读数据功能:在从机COM2中修改电压电流值,并在主机数据模式下点选“读”或者点选“批量读”(两种方式通讯协议是不一样的),以测试主机的读功能:
通讯码如下所示:
【2】测试主机写数据功能:在主机COM1中修改指令中的值,并在主机数据模式下点选“写”或者点选“批量写”(两种方式通讯协议是不一样的),从机中会显示该值被改掉,以测试主机的写功能:
通讯码如下所示:
综上所示,完成了两个虚拟连接的串口间的模拟MODBUS数据收发。
四 MODBUS协议分析:
上面的测试中,使用到了MODBUS RTU协议的0x03、0x06、0x10三种功能码(几种常用的功能码介绍:http://m.elecfans.com/article/631762.html),下面做一个简要的分析:
(1)读保持寄存器功能码0x03(区别于下面的写操作,单个读和批量读都是该功能码):
【0x03的PDU部分】:主机发---->起始地址+寄存器数量,从机回---->总字节数+数据;
批量读电压值10和电流值20报文
COM1-发送:01 03 00 00 00 02 c4 0b
COM2-接收:01 03 00 00 00 02 c4 0b
COM2-发送:01 03 04 0a 00 14 00 f6 eb
COM1-接收:01 03 04 0a 00 14 00 f6 eb
报文解析如下:
/*主机COM1发数据解析*/
01-地址
03-功能码,代表查询功能
00 00-代表查询的起始寄存器地址.说明从0x0000开始查询.
(这里需要说明以下,Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据;)
00 02-代表查询了两个寄存器.结合前面的00 00,意思就是查询从0开始的2个寄存器值;
c4 0b-循环冗余校验,是modbus的校验公式,从首个字节开始到c4前面为止;
(注:这里新手可能不懂,这个校验就是保证数据传输过程没有错误的一种手段,不同的协议这种校验公式不一样,只需了解这个就足够了,具体怎么求的,可以直接在输出数据得到结果,地址如下:http://www.ip33.com/crc.html)/*从机COM2回数据解析*/
01-地址
03-功能码
04-代表后面数据的字节数,因为上面说到,一个寄存器有4个字节,所以后面的字节数肯定是2*查询的寄存器个数;
0a 00-从机返回电压值数据10(这边是字节序为小端模式,若选择大端,这边显示00 0a)
14 00-从机返回电流值数据20
f6 eb-循环冗余校验
单个读数据大同小异,差别基本在于寄存器的个数,这边不再赘述,仅把报文在这边做一个展示:
单个读电压值10报文
COM1-发送:01 03 00 00 00 01 84 0a
COM2-接收:01 03 00 00 00 01 84 0a
COM2-发送:01 03 02 0a 00 be e4
COM1-接收:01 03 02 0a 00 be e4单个读电流值20报文
COM1-发送:01 03 00 01 00 01 d5 ca
COM2-接收:01 03 00 01 00 01 d5 ca
COM2-发送:01 03 02 14 00 b7 44
COM1-接收:01 03 02 14 00 b7 44
(2)写保持寄存器功能码0x06(区别于上面的读操作,单个写的功能码是0x06、批量写是0x10):
【0x06的PDU部分】:主机发---->起始地址+数据内容(因为你只需要修改一个,所以起始地址就是所要修改的地址),从机回---->起始地址+数据内容(发现居然一样!)
单个写电压值10报文
COM1-发送:01 06 00 00 0a 00 8f 6a
COM2-接收:01 06 00 00 0a 00 8f 6a
COM2-发送:01 06 00 00 0a 00 8f 6a
COM1-接收:01 06 00 00 0a 00 8f 6a单个写电流值20报文
COM1-发送:01 06 00 01 14 00 d7 0a
COM2-接收:01 06 00 01 14 00 d7 0a
COM2-发送:01 06 00 01 14 00 d7 0a
COM1-接收:01 06 00 01 14 00 d7 0a
针对“单个写电压值10报文”报文解析如下:
/*主机COM1发数据解析*/
01-主机要查的地址
06-功能码,代表修改单个寄存器功能,修改有些不同,有修改一个寄存器和修改多个寄存器;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
0a 00-代表修改的值为0a 00.结合前面的00 00,意思就是修改0号寄存器值为0a 00;
8f 6a-循环冗余校验,是modbus的校验公式,从首个字节开始到8f前面为止;/*从机COM2回数据解析*/
01-从机返回的地址,说明这就是主机查的从机
06-功能码,代表修改单个寄存器功能;
00 00-代表修改的起始寄存器地址.说明是0x0000.
0a 00-代表修改的值为0a 00.结合前面的00 00,意思就是修改0号寄存器值为0a 00;
8f 6a-循环冗余校验,是modbus的校验公式,从首个字节开始到8f前面为止;
(3)批量写保持寄存器功能码0x10(区别于上面的读操作,单个写的功能码是0x06、批量写是0x10):
如果我要修改多个寄存器,难道用06发好几次,这样不会太傻了吗?所以,modbus RTU协议包含了修改连续多个寄存器的方法,就是功能码为0x10。
【0x10的PDU部分】:主机发---->起始地址+寄存器个数+总字节数+数据,从机回---->起始地址+寄存器数量
批量写电压值10和电流值20报文
COM1-发送:01 10 00 00 00 02 04 0a 00 14 00 ff 77
COM2-接收:01 10 00 00 00 02 04 0a 00 14 00 ff 77
COM2-发送:01 10 00 00 00 02 41 c8
COM1-接收:01 10 00 00 00 02 41 c8
报文解析如下:
/*主机COM1发数据解析*/
01-主机要查的地址
10-功能码,代表修改多个寄存器功能;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
00 02-代表修改的寄存器数量,这里开始于0x06的修改不同;
04 -表示修改的总字节数,由于修改了2个寄存器,所以数据要有4个字节;
0a 00-主机修改电压值数据为10(结合上面,就是从第0000寄存器开始修改一个寄存器值为0a 00,就是把0000寄存器改为0a 00)
14 00-主机修改电流值数据为20
ff 77-循环冗余校验,是modbus的校验公式,从首个字节开始到ff前面为止;/*从机COM2回数据解析*/
01-从机返回的地址,说明这就是主机查的从机
10-功能码
00 00-代表修改的起始寄存器地址.说明是0x0000.
00 02-代表修改的寄存器数量,只需要回复这么多久足够了,从机告诉主机,你修改了哪几个寄存器就足够了;
41 C8-循环冗余校验;