在大家通读Modbus协议时,总是会碰到一些容易混淆的名词,从而导致对于协议的解读出现问题,在本文中,我
们对于Modbus协议中可能会给大家造成困惑的名词作相关的解释。
1.功能码:功能码在modbus协议用于表示信息帧的功能,常用的功能码有03,04,06,16等,其中03功能码的作
用是读保持寄存器内容,04功能码的作用是读输入寄存器内容(输入寄存器和保持寄存器的区别看下文),06功
能码的内容是预置单个保持寄存器,16功能码的内容则是预置多个保持寄存器。
2.输入寄存器和保持寄存器:04功能码的作用就是读输入寄存器,而03功能码的作用则是读保持寄存器,很多人
在看到这两个功能码的时候总是希望找到这两个功能码的区别,保持寄存器和输入寄存器到底是什么区别,
modbus协议最开始是用来解决PLC的通信协议问题的,主要用于输入输出数字量信号以及模拟量信号,所谓的输
入寄存器就是从模拟量信号输入引申出来的,即输入寄存器只能从模拟量信号输入端改变寄存器,而主机则不能
通过下发指令改变输入寄存器的数据,而保持寄存器则是用于输出模拟量信号的,主机是可以改变寄存器数据,
也就是说对于主机而言,输入寄存器是只读的,而保持寄存器是可以读写的,当主机用06,16功能码的指令去预
置输入寄存器的时候,设备会返回一个代码为0x81的错误代码,即企图写只读寄存器。
3.Modbus中的数据地址格式:在Modbus协议中,经常会出现类似于3xxxx,4xxxx寄存器,这个表示的是寄存器支
持的数据类型。我们用列表来说明,还有Modbus数据地址格式是从0开始,比如以下一个寄存器40009,即表示保
持寄存器,寄存器地址为00 08,类似的数据地址格式经常在组态软件以及PLC系统中用到。
映射地址 使用的功能码 地址类型 存取方式 描述
0XXXX 01,05,15 离散输出 读写 每个卷表示单个开关位
1XXXX 02 离散输入 只读 每个卷表示单个开关位
2XXXX 03,04,06,16 浮点寄存器 只读/读写 两个连续16位寄存器表示一个浮点数
3XXXX 04 输入寄存器 只读 每个寄存器表示一个16位无符号整数
4XXXX 03,06,16 保持寄存器 读写 每个寄存器表示一个16位无符号整数
5XXXX 03,04,06,16 ASCII字符 读写 每个寄存器表示两个ASCII码
4.Modbus RTU/ASCII/TCP:Modbus协议最开始是用于可编程逻辑控制器(PLC)之间的通讯,由于其具有的开放性
,大量的用于现场智能仪表。Modbus协议有多个变种,其中最著名的是Modbus RTU/Modbus ASCII和Modbus TCP
通信协议。其中RTU/ASCII协议是基于串行口通信,而TCP协议则是基于以太网通信。他们之间的区别和联系请参
考本站其他页面内容:Modbus RTU/TCP协议解析以及Modbus RTU/ASCII通信协议异同点。
5.Modbus错误代码表,modbus有功能码,校验码,异常功能码和错误代码,其中异常功能码和错误代码非常容易
混淆,一般来说异常功能码指的是某个功能码执行的时候出现的相应异常功能码,一般都是在功能码的基础上加
上0x80,比如03功能码出现的异常码是0x83异常功能码,16功能码对应出现的异常功能码则是0x90,而错误代码
则是表示出现错误的具体情况,比如寄存器地址不存在,不管是读还是写,如果该寄存器地址不存在的话,错误
代码为02。具体情况请参阅本站其他页面文章。
/***************************以上摘自http://www.485-can-tcp.com/technology/232485/TheModbus.htm********************************/
以下实际结果如下:
测试条件:组态王选择 MODBUS-TCP 做客户端, 服务器为树莓派3B,IP 192.168.1.200, 端口6000
组太王设置通信参数:192.168.1.200 :6000 22/30 //IP 192.168.1.200 PORT 6000 DEVICE 22
定义三个变量 寄存器分别是 40001 40002 40005,主界面定义三个文本框,选择模拟量输入+模拟量输出, 更新时间1000ms 连通后
组态王发送
00 00 00 00 00 06 16 03 00 00 00 05 //读取模拟量的值
00 00 为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文; 实际测试这个值没有变化 一直是00 00
00 00 表示协议标识符,00 00为modbus协议;
00 06 为数据长度,用来指示接下来数据的长度,单位字节;
16 地址码 设备地址22
03 读功能码
00 00 起始地址码 组态王从1开始计数,00 00 即40001
00 05 数据长度 5个16位数值(word数量)
回应
00 00 00 00 00 0d 16 03 0a 00 01 00 02 00 03 00 04 00 05
00 00 为此次通信事务处理标识符,应答报文要求与先前对应的请求保持一致;
00 00 为协议标识符,与先前对应的请求保持一致;
00 0d 为数据长度,用来指示接下来数据的长度,单位字节
16 设备地址 应答报文要求与先前对应的请求保持一致;
03 为功能码,正常情况下应答报文要求与先前对应的请求保持一致,如果出错则返回80h+先前的功能码;
0a 指示接下来数据的字节长度; 应该是请求的数据字节数05 x2 对应10个字节
00 01 00 02 00 03 00 04 00 05 数据高低位数值
结果组态王文本框分别显示 01 02 05
在组态王中,向40001寄存器写入 33
组态王发送
00 00 00 00 00 06 16 06 00 00 00 21
00 00 为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文; 实际测试保持00 00
00 00 表示协议标识符,00 00为modbus协议;
00 06 为数据长度,用来指示接下来数据的长度,单位字节;
06 写单保持寄存器功能码
16 地址码 设备地址22
00 00 单保持寄存器地址,这里是40001
00 21 单保持寄存器数据,00 21 即33
回应
00 00 00 00 00 06 16 06 00 00 00 21
00 00 为此次通信事务处理标识符,应答报文要求与先前对应的请求保持一致;
00 00 为协议标识符,与先前对应的请求保持一致;
00 06 为数据长度,用来指示接下来数据的长度,单位字节
16 设备地址 应答报文要求与先前对应的请求保持一致;
06 为写功能码,正常情况下应答报文要求与先前对应的请求保持一致,如果出错则返回80h+先前的功能码
00 00 单保持寄存器地址,这里是40001
00 21 单保持寄存器数据,00 21 即33
即原封不动的将数据发回去
测试过程中没有出现任何通讯错误, 树莓派检测组态王发送来的数据,也没有发现任何不合理数据。
在不给组态王发送数据或者一直发送错误数据的情况下,组态王会间断的发送 00 00 00 00 00 06 16 01 ff ff 00 01, 不知为何,01是读线圈的命令码,解析后是读地址为ffff的一个线圈的状态,不明白是心跳检测还是别的 没有找到相关资料,在检测到这个报文的时候我原封不动的发回去,未见任何异常。望有高人指点!