
----------------------------------------------------------------------------------------------------......
-------------------------------------------------------------------------------------------------------------------

这张是FX3U做为从站时,各软元件的MODBUS地址
记住:以下所有的数据,都是以16进制体现的!!!
01H功能码:线圈读出,可以读出1个或多个线圈的状态(ON/OFF)
例1:读取FX3U的M0-M10这11个线圈的当前状态,我们在PLC中将M0-M10都设置为1
主站发送报文如下:01010000000B7DCD
从站返回报文如下:010102FF07B9CE

例2:读取FX3U的Y0-Y7这8个线圈的当前状态,我们将Y3置为0,其余置为1
主站发送报文如下:01088
从站返回报文如下:010101F7100E

例3:读取FX3U的Y10单个线圈的当前状态,我们将Y10置为1
主站发送报文如下:0104C;这里要注意的是Y10的地址,由于Y线圈是8进制的,而Y线圈的MODBUS地址是十进制的,因此这里的Y10的地址应该是H3308(3300+8)
从站返回报文如下:010101019048

重点:这里的字节数是以8个位为单位,不足8位的数据,字节数依旧为1个字节数。比如M0-M10,这里有11个位,11=8+3,后面的3不足8位,因此依旧是要写成2个字节数的!!!
02H功能码:读出1个或多个离散输入的状态(ON/OFF)
例1:读取FX3U的X0-X10这9个输入点的当前状态,当前的X2,X5X10都点亮,其余为灭。
主站发送报文如下:010234000009B63C
从站返回报文如下:01020224016378

例2:读取FX3U的X11单个输入的当前状态,当前X11是点亮的。
主站发送报文如下:01023409000167F8;这里也要注意X11的地址
从站返回报文如下:010201016048

03H功能码:读出1个或多个保持寄存器的值
例1:读取FX3U的D1000-D1010这11个寄存器的值,D1000=100,D1001=101,D1002=102,D1003=103,D1004=104,D1005=105,D1006=106,D1007=107,D1008=D108,D1009=109,D1010=110
主站发送报文如下:010303E8000B847D;(11个寄存器,就是11个点数,11换成16进制就是0B)
从站返回报文如下:01031600606700680069006A006B006C006D006EF039

例2:读取FX3U的D1100单个寄存器的值
主站发送报文如下:0103044C000144ED
从站返回报文如下:0103020063F86D

04H:读出1个或多个输入寄存器的值。
例1:读取FX3U的D1000-D1010这11个寄存器的值
主站发送报文如下:010403E8000B31BD
从站返回报文如下:01041600606700680069006A006B006C006D006E6613

例2:读取FX3U的D1100单个寄存器的值
主站发送报文如下:0104044C0001F12D
从站返回报文如下:0104020063F919

在FX3U中输入寄存器和保寄存器是同一个寄存器。而在FX5U中,输入寄存器是不存在的。并且通过测试结果可知,H03和H04功能码的功能是一样的,怪不得FX5U中把输入寄存器给取消掉了呢。
05H:在1个线圈中写入值(ON/OFF)
例1:将FX3U中的M100置1
主站发送报文如下:01050064FF00CDE5
从站返回报文如下:01050064FF00CDE5

例2:将FX3U中的M100置0
主站发送报文如下:0105006400008C15
从站返回报文如下:0105006400008C15

06H:在1个保持寄存器中写入值。
例1:将FX3U中的D0写入100
主站发送报文如下:0106000000648821
从站返回报文如下:0106000000648821

例2:将FX3U中的D0写入-100
主站发送报文如下:01060000FF9CC853
从站返回报文如下:01060000FF9CC853

特别注意:我这里的-100是根据PLC里的-100的二进制数再手动转换为16进制数后填入到报文中的。真正在进行数据交换的时候,直接在主站的寄存器中填入-100即可,然后从站接收到的寄存器数据直接拿来用即可。
另外还有一点,由于06H功能码只能写入1个保持寄存器,因此它的数据范围只能是-32768到32767,且不能为浮点数。因为浮点数需要2个寄存器(即4个字节)来表示。
0FH:在批量(1个或多个)线圈中写入值(ON/OFF)
例1:将FX3U中的M0-M10的这11个线圈分别写入:(M10)10101110011(M0)
573

根据手册,它的写入顺序是先低位,再高位,因此73放在前,05放在后。大家也可以尝试将05放前,73放后看看是你想要的结果,或者说是否按照先低后高的顺序写入的?
主站发送报文如下:010F0000000B02730501F7;
从站返回报文如下:010F0000000B140C

例2:将FX3U中的M0单个线圈置1
主站发送报文如下:010F000000010101EF57;这里黄色标记的是让M0置为1的数值,并且只能填01,不能填0001,因为它的前面是01,表示1个字节,如果填了0001,那就是2个字节,就会出现下面的异常返回码:018F030431

从站返回报文如下:010F00000001940B

例3:将FX3U中的M0单个线圈置0
主站发送报文如下:010F0000000101002E97
从站返回报文如下:010F00000001940B

10H:在批量寄存器中写入值。
例1:将FX3U中的D1000-D1007这8个寄存器分别写入值:1.2,65535.0,-100.0,-35.99
由于浮点数需要占用2个寄存器,因此一共需要8个寄存器。
其中,D1000-D1001存储1.2,并且1.2在32位寄存器中的值的表示方式如下图所示,因此D1000=999A,D1001=3F99

根据这个方法,下面的几个数据也可以按照高低寄存器的方式来存储。

D1002-D1003存储65535.0
D1002=FF00,D1003=477F
D1004-D1005存储-100.0
D1004=0000,D1005=C2C8
D1006-D1007存储-36.99
D1006=F5C3,D1007=C20F
主站发送报文如下:011003EA3F99FF00477F0000C2C8F5C3C20FEDB8
从站返回报文如下:011003E8000841BF

例2:将FX3U中的D2000单个寄存器写入值:-3.14
主站发送报文如下:011007D0000204F5C3C0484B05;虽然是单个,但是浮点数需要2个寄存器来存储,因此实际还是对2个寄存器进行写入。
从站返回报文如下:011007D000024145

17H:进行批量保持寄存器的读出/写入。处理过程为实施写入后再进行读出。
例1:将FX3U中的D0-D10写入值:0,1,2,3,4,5,6,7,8,9,10
读出D20-D30的值:预设100,101,102,103,104,105,106,107,108,109,110
主站发送报文如下:01170014000B0000000B16000000010002000300000700080009000A7126
从站返回报文如下:0150066006700680069006A006B006C006D006E4F79

例2:将FX3U中的D50写入值:555(想验证是否可以读取1个寄存器)
读出D52的值:预设666
主站发送报文如下:01032000102022B50E9
从站返回报文如下:011702029A3CBF

好了,以上就是各个功能码的实际收发报文时的情况,大家可以尝试着去做做。
下一集,我会讲讲MODBUS主站功能,通过2台三菱PLC来进行主从通信。
敬请关注