当前位置:网站首页 > Haskell函数式编程 > 正文

modbus RTU报文格式(modbus RTU报文格式响应高低位合并)



功能码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格式),读取数值即0(转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 (低八位先转十六进制为 EE) (10补0到8位为00000010转十六进制为 02) +校验码 

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

功能码06:写单路寄存器

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

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

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

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

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

主站报文格式:从机地址+功能码+起始地址+写入寄存器数量+字节计数(写入寄存器数量*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+校验码

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

到此这篇modbus RTU报文格式(modbus RTU报文格式响应高低位合并)的文章就介绍到这了,更多相关内容请继续浏览下面的相关 推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 字符串转换编码(字符串转换编码格式)2026-02-13 18:27:06
  • WORD文章多级标题快速划分,论文写作必备技能,规范文章轻松办公多级列表样式怎么设置(如何对WORD文章多级标题快速划分,论文写作必备技能,规范文章轻松办公设置多级列表)2026-02-13 18:27:06
  • ddpm模型公式(ddm模型中的k指什么)2026-02-13 18:27:06
  • py文件用什么软件打开手机(py文件格式用什么打开)2026-02-13 18:27:06
  • 反激电路可以升压吗(反激电路输出电压公式推导)2026-02-13 18:27:06
  • esp32 udp广播(esp32udp广播模式)2026-02-13 18:27:06
  • docker 四种网络模型(docker的五种网络模式总结)2026-02-13 18:27:06
  • 免费海报制作模板图片(海报制作模板图片word格式下载)2026-02-13 18:27:06
  • mtf调制函数(调制信号m(t)=acosωt+acos2ωt)2026-02-13 18:27:06
  • cmip6模式下载(cmip6官网)2026-02-13 18:27:06
  • 全屏图片