网站首页 > 技术文章 正文
Modbus RTU通讯协议在数据通讯上采用主从应答的方式进行。只能由主机(PC,HMI等)通过唯一从机地址发起请求,从机(终端设备)根据主机请求进行响应,即半双工通讯。该协议只允许主机发起请求,从机进行被动响应,因此从机不会主动占用通讯线路造成数据冲突。
类似Modbus RTU协议的主从应答协议还有西门子的PPI、电表常用的DL/T645-2007等协议。
一、协议格式
信息传输为异步方式,使用16进制进行通讯,信息帧格式:
地址码 | 功能码 | 数据区 | CRC校验码 |
1字节 | 1字节 | N字节 | 2字节 |
地址码
地址码是每个通讯信息帧的第一个字节,一般支持1到247,部分设备也支持0地址,用于接收主机的广播数据,每个从机在总线上地址必须唯一,只有与主机发送的地址码相符的从机才能响应返回数据。
功能码
功能码是每个通讯信息帧的第二个字节。主机发送,通过功能码告知从机设备应当执行何种操作。
常见的八种功能码:
功能码 | 定义 | 操作 |
01H | 读取线圈 | 读取一个或多个连续线圈状态 |
05H | 写单个线圈 | 操作指定位置的线圈状态 |
0FH | 写多个线圈 | 操作多个连续线圈状态 |
02H | 读取离散量输入 | 读取一个或多个连续离散输入状态 |
04H | 读取输入寄存器 | 读取一个或多个连续输入寄存器数据 |
03H | 读保持寄存器 | 读取一个或多个保持寄存器数据 |
06H | 写单个保持寄存器 | 把两个十六进制数据写入对应位置 |
10H | 写多个保持寄存器 | 把4*N个十六进制数据写入N个连续保持寄存器 |
数据区
数据区随功能码以及数据方向的不同而不同,这些数据可以是“寄存器首地址+读取寄存器数量”、“寄存器地址+操作数据”、“寄存器首地址+操作寄存数量+数据长度+数据”等不同的组合,在“功能码分析”详解不同功能码的数据区。
Modbus CRC校验
Modbus RTU协议常用与工业现场对数据传输的稳定性和正确性有较高的要求,因此通过CRC校验保证数据传输的正确性和完整性。
二、错误反馈
地址与CRC校验错误并不会收到从机的数据反馈,其他错误将向主机返回错误码。数据帧的第二位加上0X80表示请求发生错误(非法功能码、非法数据值等),错误数据帧如下:
地址码 | 功能码 | 错误码 | CRC校验码 |
1字节 | 1字节 | 1字节 | 2字节 |
常见错误码如下:
值 | 名称 | 说明 |
01H | 非法的功能码 | 不支持该功能码操作寄存器 |
02H | 非法的寄存器地址 | 访问设备禁止访问的寄存器 |
03H | 非法的数据值 | 写入不支持的参数值 |
04H | 从机故障 | 设备工作异常 |
三、通讯信息传输过程
通讯命令由主机发送从机时,与主机发送的地址码相符的从机接收通讯命令,如果CRC校验无误,则执行相应的操作,然后把执行结果(数据)返回给主机。返回信息中包含地址码、功能码、执行后的数据以及CRC校验码。如果地址不匹配或者CRC校验出错就不返回任何信息。
四、功能码分析
功能码01H:读线圈
例如:主机要读取从机地址为01H,起始线圈地址为00H的1个线圈状态,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 01 | |
起始线圈地址 | 高字节 | 00 |
低字节 | 00 | |
线圈数量 | 高字节 | 00 |
低字节 | 01 | |
CRC校验 | 低字节 | FD |
高字节 | CA |
如果从机寄存器00H线圈闭合,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 01 | |
字节数 | 01 | |
线圈状态 | 01 | |
CRC校验码 | 低字节 | 90 |
高字节 | 48 |
仿真演示:
功能码05H:写单个线圈
例如:主机要控制从机地址为01H,线圈地址为0000H的线圈状态,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 01 | |
线圈地址 | 高字节 | 00 |
低字节 | 00 | |
控制方式 | 高字节 | 00(断开)、FF(闭合) |
低字节 | 01 | |
CRC校验 | 低字节 | XX |
高字节 | XX |
从机返回与主机请求相同;
仿真演示:
功能码0FH:写多个线圈
例如:主机要控制从机地址为01H,起始线圈地址为00H的4个线圈状态,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 0F | |
起始线圈地址 | 高字节 | 00 |
低字节 | 00 | |
线圈数量 | 高字节 | 00 |
低字节 | 04 | |
写入字节数 | 01 | |
控制方式 | 00(全部断开)、0F(全部闭合) | |
CRC校验 | 低字节 | XX |
高字节 | XX |
功能码0FH操作,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 0F | |
起始线圈地址 | 高字节 | 00 |
低字节 | 00 | |
线圈数量 | 高字节 | 00 |
低字节 | 04 | |
CRC校验 | 低字节 | 54 |
高字节 | 08 |
仿真演示:
功能码02H:读离散输入
例如:主机要读取从机地址为01H,起始离散量地址为00H的4个输入状态,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 02 | |
起始离散量地址 | 高字节 | 00 |
低字节 | 00 | |
读取数量 | 高字节 | 00 |
低字节 | 04 | |
CRC校验 | 低字节 | 79 |
高字节 | C9 |
如果从机首地址00H开始的4离散输入全部检测到输入,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 02 | |
字节数 | 01 | |
离散输入状态 | 0F | |
CRC校验码 | 低字节 | E1 |
高字节 | 8C |
仿真演示:
功能码04H:读取输入寄存器
例如:主机要读取从机地址为01H,起始寄存器地址为02H的1个输入寄存器数据,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 04 | |
起始寄存器地址 | 高字节 | 00 |
低字节 | 02 | |
寄存器数量 | 高字节 | 00 |
低字节 | 01 | |
CRC校验 | 低字节 | 90 |
高字节 | 0A |
如果从机输入寄存器02H的数据为3344H,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 04 | |
字节数 | 02 | |
寄存器05H数据 | 高字节 | 33 |
低字节 | 44 | |
CRC校验码 | 低字节 | AD |
高字节 | F3 |
仿真演示:
功能码03H:读保持寄存器
例如:主机要读取从机地址为01H,起始寄存器地址为05H的2个保持寄存器数据,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 03 | |
起始寄存器地址 | 高字节 | 00 |
低字节 | 05 | |
寄存器数量 | 高字节 | 00 |
低字节 | 02 | |
CRC校验 | 低字节 | D4 |
高字节 | 0A |
如果从机保持寄存器05H、06H的数据为1122H、3344H,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 03 | |
字节数 | 04 | |
寄存器05H数据 | 高字节 | 11 |
低字节 | 22 | |
寄存器06H数据 | 高字节 | 33 |
低字节 | 44 | |
CRC校验码 | 低字节 | 4B |
高字节 | C6 |
仿真演示:
功能码06H:写单个保持寄存器
例如:主机写入9988H的数据给从机地址为01H,寄存器地址为0050H的寄存器,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 06 | |
寄存器地址 | 高字节 | 00 |
低字节 | 50 | |
写入值 | 高字节 | 99 |
低字节 | 88 | |
CRC校验 | 低字节 | E3 |
高字节 | ED |
从机返回与主机请求相同;
功能码10H:写多个保持寄存器
例如:主机要把数据0005H、2233H保存到从机地址为01H,起始寄存器地址为0020H的2个寄存器中,主机发送:
主机发送 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 10 | |
起始寄存器地址 | 高字节 | 00 |
低字节 | 20 | |
寄存器数量 | 高字节 | 00 |
低字节 | 02 | |
写入字节数 | 04 | |
0000H 寄存器待写入 | 高字节 | 00 |
低字节 | 05 | |
0001H 寄存器待写入 | 高字节 | 22 |
低字节 | 33 | |
CRC校验 | 低字节 | B9 |
高字节 | 03 |
功能码10H操作,从机返回:
从机返回 | 发送数据(HEX) | |
地址码 | 01 | |
功能码 | 10 | |
起始寄存器地址 | 高字节 | 00 |
低字节 | 20 | |
寄存器数量 | 高字节 | 00 |
低字节 | 02 | |
CRC校验 | 低字节 | 40 |
高字节 | 02 |
仿真演示:
猜你喜欢
- 2025-05-15 总结雅虎前端性能优化技巧(16条)
- 2025-05-15 日常生活中吃雪莲果有养生功效也有危害
- 2025-05-15 API 安全之认证鉴权
- 2025-05-15 Chaosblade: 阿里一个超级牛逼的混沌实验实施工具
- 2025-05-15 膨来仙岛丨搞电竞的都是什么成分?
- 2025-05-15 大事全知晓!2022年新闻日历来了!
- 2025-05-15 你是有多久没看过麦田圈了?一篇文章全面回顾2015麦田圈季
- 2025-05-15 魔兽世界9.1 刻希亚寻找宝箱、稀有WA(转自nga)
- 2025-05-15 高衙内欺辱林冲妻子林娘子,他到最后得手了吗?结局很悲凉
- 2025-05-15 线粒体超氧化物荧光探针:MitoSOX Green的核心特性
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 517℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 489℃MySQL service启动脚本浅析(r12笔记第59天)
- 468℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 466℃启用MySQL查询缓存(mysql8.0查询缓存)
- 446℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 426℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 423℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)