ModbusRTU学习笔记

功能码01:读取线圈状态

主站发报文,从站反报文

主站发送报文格式:从站地址+功能码+起始地址(16进制xx xx格式)+读取线圈长度(16进制xxxx格式)+校验码

从站返回报文格式:从站地址+功能码+字节数(线圈长度/8,向上取整)(XX格式,即线圈最大长度是FF转十进制就是255)+读取数值(8个线圈就是XX,16个线圈就是XX XX)+校验码

举两个例子

例一:主站配置(modbus poll)

从站地址即SlaveId=1,功能码即Function 中的01,起始地址即Address=1(格式是XX XX),读取线圈数即Quantity=9

所以主站发送报文应该是:从站地址+功能码+起始地址(16进制xxxx格式)+读取线圈长度(16进制xxxx格式)+校验码

01 01 00 01 00 09 +校验码

从站配置

从站地址=1,功能码=01,字节数=读取线圈数/8=9/8(向上取整)=2(XX格式),读取数值即011111111(转16进制数为FF,因为字节数是2所以格式是 XX XX,如果字节数是1则是XX)+校验码

所以从站返回报文应该是:从站地址+功能码+字节数(线圈长度/8,向上取整)(XX格式,即线圈最大长度是FF转十进制就是255)+读取数值(8个线圈就是XX,16个线圈就是XX XX)+校验码

01 01 02 FF 00 +校验码

自己推出:发送-》01 01 00 01 00 09 +校验码

                返回-》01 01 02 FF 00 +校验码

测试得出:一致

疑问:为什么字节数是1读取的数值位是XX呢

应为1个字节=8位最大时为 1111 1111转16进制就是FF,所以就是XX代替啦!

功能码02:读取输入状态

读取输入状态(功能码02)与01报文格式基本一样。只是02效率按字节读取,01是按位读取,如果读取线圈长度是8的倍数用02效率更合适

功能码03:读取保持寄存器

主站发送报文格式:从站地址+功能码+起始地址(16进制xx xx格式)+读取寄存器长度(16进制xx xx格式,一个寄存器等于2个字节,按道理来说最大也是存储FFFF转10进制就是65535,但是好像存不了那么大,后面再来看)+校验码

从站返回报文格式:从站地址+功能码+读取字节数(读取寄存器长度*2,XX格式)+读取的数值(XX XX)+校验码

如:主站发送报文格式:01 03 00 00 00 02 +校验码          读取两个寄存器长度

那么从站发送的报文格式应该是:01 03 04 xx xx(寄存器1的值) xx xx(寄存器2的值)+校验码

功能码04:读多路输入寄存器

报文格式和03一样,和03的区别在于读取的存储器不一样,03表示读取保持寄存器,04读取的是输入寄存器。

功能码05:写1路开关量输出(有些地方叫强制单线圈(功能码05))

当我写到这里的时候,我开始纳闷了,怎么从站可选的功能码没有05,查了资料后才知道:

相对modbus Slave设置

主站用功能码0X01,0X05,0X0F的时候,从站对应的都是01功能码

主站用功能码0X03,0X06,0X10的时候,从站对应的都是03功能码

真正的从站返回报文还是和主站发送的报文功能码部分一致的。

主站发送报文格式:从机地址+功能码+起始地址+控制命令(格式xx xx 其中FF00表示合即写入线圈值1,0000表示分即写入线圈值0)+校验码

从站返回报文格式:从机地址+功能码+起始地址+控制命令+校验码(同)

因为05功能码只用于写入单线圈

功能码XX0F:写多路开关量输出

简而言之就是一次写入线圈(布尔值)

主站发送报文格式:从机地址(xx)+功能码(xx)+起始地址(xx xx)+写入线圈数量(xx xx)+字节数(xx)+数据1(XX)+数据2+...+校验码    (空的数据为用01来补)

从站发送报文格式:从机地址+功能码+起始地址+写入线圈数量(即强制线圈数)+校验码(同

实践一下吧!

准备从地址00 0A开始写入数值  0 1 1 1 0 1 1 1 0 1  这10个数值

分析得到的发送报文是:01 0F 00 0A 00 0A 00 02 00 00 FF 00 FF 00 FF 00 00 00 FF 00 FF 00 FF 00 00 00 FF 00 +校验码 

分析得到的返回报文是:01 0F 00 0A 00 0A+校验码

结果是

我写的数据区有差异,这里数据区应该转成16进制发送,10个线圈 要用2个字节即2个XX表示

所以正确的主站发送报文的格式应该是:

01 0F 00 0A 00 0A 02 (11101110第八位先转十六进制为 EE) (10补0到8位为00000010转十六进制为 02) +校验码 

最终主站发送报文:01 0F 00 0A 00 0A EE 02+校验码

功能码06:写单路寄存器

主站报文格式:从机地址+功能码+寄存器地址+写入数据(xx xx)+校验码

从站返回格式:与主站发出格式一致。

例子:将00 02地址的寄存器值写入100

主站发送报文格式:01 06 00 02 00 64+校验码

功能码0X10:写多路寄存器


描述:主机利用这个功能码把多个数据保存到PDM表的数据存储器中去。Modbus通讯规约中的寄存器指的是16位(2个字节或1个字),并且高位在前,低位在后。这样PDM的存储器都是2个字节。由于Modbus通讯规约允许每次最多保存60个寄存器,因此PDM一次也最多允许保存60个数据寄存器(这部分解释是借鉴他人的描述)自己的理解就是一次可以写入多个寄存器,一次报文最多写入60个值即60个寄存器

主站报文格式:从机地址+功能码+起始地址+写入寄存器数量+字节计数(写入寄存器数量*2 格式 xx)+写入数据1+写入数据2.......+校验码

从站返回报文:从机地址+功能码+起始地址+写入寄存器数量+校验码

那就实践一个试试喽!

准备发送的数据是   100 110 120 130 140 150 160 170 180 190 这10个数值

所以主站发送的报文应该是:01+10 +00 02+00 0A+14 +00 64+ 00 6E+00 78+00 82+00 8C+00 96+00 A0+00 AA+00 B4+00 BE+校验码

即01 10 00 02 00 0A 14 00 64 00 6E 00 78 00 82 00 8C 00 96 00 A0 00 AA 00 B4 00 BE+校验码

从站返回报文:01+10+00 02+00 0A+校验码

01 10 00 02 00 0A+校验码

新手,如果错误请大佬指正

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值