Modbus-TCP/IP

功能码详解


对于modbus来说,设计的功能码也就是0x01、0x02、0x03、0x04、0x05、0x06、0x0F、0x10,其实分类来说只有两种,即线圈(开关量)和寄存器(模拟量),也就是位读写和字节读写,首先要弄清楚功能码不一样,对应数据的解析规则也不一样,下面就针对不同的情况来说明:

  • 在modbus服务端,数据是使用地址的方式来公开的,因为服务端保存了很多数据,你想要访问某个数据,肯定需要制定唯一的身份标识。

  • 对于位操作来说(各种线圈和离散量),一个地址代表一个bool变量,即0和1.一个地址代表了2个byte,共有65536中方式。比如我们读取地址0的寄存器,返回00 00 及代表寄存器0数据为0,如果返回 01 00,那么代表寄存器数据为 256

  • 功能码 0x01 读线圈

byte[0] byte[1] :消息号,发送指令的时候是多少就是多少
byte[2] byte[3] :必须都为0,代表这是modbus通讯
byte[4] byte[5] :byte[5]后面的数字是所有的字节数,如果后面有100个,那么这里就是00 64
byte[6] :站号,之前写FF 那么这里也写FF
byte[7] :功能码,之前写01功能码,这里就是01,和我们发送的指令一致
byte[8] 指示后面跟随的字节数量,因为byte[8]后面的就是真实的数据,我们最终想要的结果就在byte[8]后面
byte[9]:真实数据,我们真正想要的东西,我们知道一个byte有8位,但是我们读取了一个位数据(开关量),所以这里有效值是byte[9]的最低位,二进制为0000 0000 我们看到最低位为0,所以最终我们读取的地址0的线圈为断。

假设我们要读取地址10开始的共10个线圈,我们发送
00 00 00 00 00 06 FF 01 00 0A 00 0A
接收到的是:
00 00 00 00 00 05 FF 01 02 79 01
我们读取了10个位,那么一个byte可以表示8个位,因此需要2个byte,所以数据长度为02,想要的数据是 79 01
0111 1001 0000 0001
将二进制的顺序颠倒:
1001 1110 1000 0000
线圈10-线圈19的通断情况是:通断断通 通通通断 通断 再后面的0是无效的,这里读取10个位长度

  • 功能码 0x02

和上面基本一致

  • 功能码 0x05

这个功能码是实现数据写入,他能实现什么功能呢?我们可以利用这个功能来制定谋略线圈通或断
比如我们要制定地址0的寄存器为通:00 00 00 00 00 06 FF 05 00 00 FF 00 含义和前面都是一致的,我们分析05 00 00 FF 00
05 是功能码 00 00 是我们指定的地址,如果我们想写地址1000通,那么就是03 E8,至于FF 00是规定的数据,如果你想地址线圈通,就填这个值,想制定线圈为断开,就填00 00 其他任何值都对结果无效。

  • 功能码0x0F

前面已经实现了0x05单线圈写入,我们可以指定线圈100为通,其实就两个信息需要指定,线圈地址是什么,通还是断,然后我们就可以自然而然的写出指令码了。但是现在我们需要实现一个功能时,将地址0...999共计1000个线圈全部为off这时候就用到0x0f这个功能码,就是批量写入。
00 00 00 00 00 84 FF 0F 00 00 03 E8 7D ...后面就是125个byte,都是00

  • 功能码 0x03

该功能实现寄存器的数据读取,我们需要知道的是,一个寄存器占2个字节,而且是高位在前,低位在后,那么如果寄存器0的数据是1000,那么我们读取的数据就是03 E8,03功能码和01功能码很接近,就是功能码替换一下,返回的数据解析不一样而已。

posted @ 2023-06-11 16:53  丹心石  阅读(597)  评论(0编辑  收藏  举报