modbus tcp 跟 modbus rtu
文章目录
- 简述
- 核心区别对比
- Modbus 对照表
- 什么是 CRC 校验?
- 通信流程示例(Modbus RTU 模式)
简述
Modbus TCP 和 Modbus RTU 是 Modbus 协议的两种主流实现,核心区别在于传输层和物理层,前者用以太网,后者用串行总线。
核心区别对比
对比维度 | Modbus TCP | Modbus RTU |
---|---|---|
传输介质 | 以太网(网线、光纤等) | 串行总线(RS-485、RS-232 等) |
数据帧结构 | 包含 IP 地址、端口号(默认 502),无校验位 | 包含从站地址,需配置波特率、校验位(奇 / 偶 / 无) |
传输速度 | 快,依赖以太网带宽(通常 10/100/1000Mbps) | 慢,受串行总线限制(常见 9600-115200bps) |
传输距离 | 远,可通过路由器、交换机扩展(理论无上限) | 近,RS-485 单段最大约 1200 米 |
设备数量 | 无理论限制,仅受网络容量影响 | 有限制,RS-485 总线最多连接 32 个从站 |
适用场景 | 工业以太网环境(如车间局域网、远程监控) | 短距离、小范围设备(如现场传感器、变频器) |
Modbus 对照表
Modbus 常用功能码与寄存器操作对照表,包含功能码含义、对应寄存器类型、操作权限及典型应用场景
功能码 | 功能描述 | 操作的寄存器类型 | 读写权限 | 数据长度限制 | 典型应用场景 |
---|---|---|---|---|---|
01 | 读取线圈状态 | 线圈寄存器(Coils) | 只读 | 最多 2000 个线圈 | 查看多个开关设备状态(如多个阀门的开 / 关状态、指示灯亮灭) |
02 | 读取离散输入状态 | 离散输入寄存器 | 只读 | 最多 2000 个输入点 | 查看外部传感器的开关量输入(如光电传感器是否检测到物体、限位开关状态) |
03 | 读取保持寄存器 | 保持寄存器 | 只读 | 最多 125 个寄存器 | 读取设备的模拟量数据或参数(如温度、压力、转速、设定值) |
04 | 读取输入寄存器 | 输入寄存器 | 只读 | 最多 125 个寄存器 | 读取实时采集的模拟量数据(如电流、电压、流量的实时测量值) |
05 | 写入单个线圈 | 线圈寄存器(Coils) | 只写 | 1 个线圈 | 控制单个开关设备(如启动 / 停止电机、打开 / 关闭单个阀门) |
06 | 写入单个保持寄存器 | 保持寄存器 | 只写 | 1 个寄存器 | 修改单个设备参数(如设定变频器的目标转速、调整 PID 控制器的比例系数) |
15 | 写入多个线圈 | 线圈寄存器(Coils) | 只写 | 最多 1968 个线圈 | 批量控制多个开关设备(如同时启动多个电机、切换一组指示灯的状态) |
16 | 写入多个保持寄存器 | 保持寄存器 | 只写 | 最多 123 个寄存器 | 批量修改设备参数(如一次性设置多个温度传感器的报警阈值、配置多组运行参数) |
特殊功能码(较少见但重要)
功能码 | 功能描述 | 适用场景 |
---|---|---|
07 | 读取异常状态 | 查看从设备的故障 / 异常状态(如:传感器通信错误、设备过载报警) |
17 | 读取 / 写入文件记录 | 操作设备内部的文件数据(如:存储历史日志、批量备份 / 恢复设备参数) |
22 | 掩码写入寄存器 | 只修改寄存器中的特定位(如:单独开启某设备的某个功能,不影响其他配置) |
什么是 CRC 校验?
CRC(Cyclic Redundancy Check,循环冗余校验)是一种数据校验算法,通过对传输的二进制数据进行计算,生成一个固定长度的校验值(Modbus RTU 中为 2 字节,16 位),附加在报文末尾。接收方会对收到的数据重新计算 CRC 值,若与附加的校验值一致,则认为数据传输无误;否则判定为通信错误,会丢弃该报文。
Modbus RTU 中 CRC 校验的工作流程
- 发送方计算 CRC:
- 主设备(或从设备)在组装完报文主体(地址、功能码、数据等)后,对这些数据按 CRC16 算法计算出一个 2 字节的校验值,附加在报文末尾。
- 例如,发送报文 [01][03][00][00][00][02](读取从站 01 的 2 个保持寄存器),计算出的 CRC 为 [C4][0B],最终发送的完整报文为:[01][03][00][00][00][02][C4][0B]
- 接收方验证 CRC:
- 接收设备收到完整报文后,忽略末尾的 2 字节 CRC,对前面的所有数据重新计算 CRC。若计算结果与收到的 CRC 一致,则处理该报文;否则视为无效数据,不响应或返回错误。
Modbus 中 CRC16 的算法细节
Modbus RTU 采用的是 CRC16-IBM 标准(多项式为 0xA001),具体计算步骤如下(简化版):
- 初始化一个 16 位寄存器(CRC 寄存器)为 0xFFFF。
- 依次取报文中的每个字节,与 CRC 寄存器的低 8 位进行异或运算。
- 对 CRC 寄存器进行右移 1 位,若移出位为 1,则将寄存器与 0xA001 异或;否则直接右移。
- 重复步骤 3,直到该字节的 8 位全部处理完毕。
- 处理完所有字节后,CRC 寄存器的值即为最终的校验值(注意:Modbus 中会将高低字节交换后附加到报文)。
通信流程示例(Modbus RTU 模式)
以 “PLC 读取传感器的温湿度” 为例,完整流程如下:
主设备(PLC)发送请求帧功能码用 03(读取保持寄存器),请求读取传感器(从站地址 0x01)的温度(寄存器 0x0000)和湿度(寄存器 0x0001):[01][03][00][00][00][02][C4][0B]
- 01:从站地址
- 03:功能码(读保持寄存器)
- 00 00:起始寄存器地址
- 00 02:读取寄存器数量(2 个:温度 + 湿度)
- C4 0B:CRC 校验位(串行通信的错误检测)
从设备(传感器)返回响应帧传感器收到请求后,返回温度(25.5℃ → 255)和湿度(60% RH → 600):[01][03][04][00][FB][02][58][75][3B]
- 01:从站地址(确认是自己的响应)
- 03:功能码(与请求一致)
- 04:返回数据长度(4 字节)
- 00 FB:温度值(255 → 25.5℃)
- 02 58:湿度值(600 → 60.0% RH)
- 75 3B:CRC 校验位
主设备解析数据
PLC 收到响应后,将二进制数据转换为实际物理量(255÷10=25.5℃,600÷10=60% RH),完成一次通信。
以水泵作为 Modbus 从设备为例,能更具体地理解协议在实际工业设备中的应用。水泵通常通过 Modbus 协议与主设备(如 PLC、触摸屏)通信,实现状态监控和远程控制
水泵的 Modbus 寄存器映射(示例)
水泵的核心参数(状态、指令、数据)会映射到 Modbus 寄存器,不同厂商定义可能不同,但逻辑类似:
寄存器类型 | 地址(0 基) | 功能描述 | 读写权限 | 数据含义(示例) | 对应功能码操作 |
---|---|---|---|---|---|
线圈寄存器 | 0x0000 | 水泵运行 / 停止控制 | 读写 | 1 = 运行,0 = 停止 | 05(单线圈写入)、01(读取) |
线圈寄存器 | 0x0001 | 故障复位 | 只写 | 1 = 触发复位,0 = 无动作(脉冲指令) | 05(单线圈写入) |
离散输入寄存器 | 0x0000 | 水泵实际运行状态 | 只读 | 1 = 正在运行,0 = 已停止 | 02(读取) |
离散输入寄存器 | 0x0001 | 故障报警状态 | 只读 | 1 = 有故障,0 = 正常 | 02(读取) |
保持寄存器 | 0x0000 | 设定频率(转速) | 读写 | 数值 = 频率值 ×10(如 500 表示 50.0Hz) | 03(读取)、06(写入) |
保持寄存器 | 0x0001 | 实际运行频率 | 只读 | 数值 = 实际频率 ×10(如 485 表示 48.5Hz) | 03(读取) |
保持寄存器 | 0x0002 | 电流检测值 | 只读 | 数值 = 电流值 ×100(如 350 表示 3.50A) | 03(读取) |
保持寄存器 | 0x0003 | 故障代码 | 只读 | 0 = 无故障,1 = 过载,2 = 欠压,3 = 过流 | 03(读取) |
- 通信示例:主设备控制水泵运行并读取状态
- 假设水泵的从站地址为 0x05,主设备(PLC)需要完成两个操作:
- 启动水泵(写入单个线圈)
- 目标:控制线圈寄存器 0x0000(运行 / 停止位)为 1(运行)。
- 功能码:05(写入单个线圈)。
- 报文结构:
- [05][05][00][00][FF][00][8C][3A]
- 05:从站地址(水泵地址)
- 05:功能码(写入单个线圈)
- 00 00:线圈地址(0x0000)
- FF 00:写入值(1=0xFF00,0=0x0000)
- 8C 3A:CRC 校验位
- 读取水泵运行状态和电流(读取保持寄存器)
- 目标:读取保持寄存器 0x0001(实际频率)和 0x0002(电流值)。
- 功能码:03(读取保持寄存器)。
- 报文结构:[05][03][00][01][00][02][74][0A]
- 05:从站地址
- 03:功能码(读取保持寄存器)
- 00 01:起始地址(从 0x0001 开始)
- 00 02:读取数量(2 个寄存器)
- 74 0A:CRC 校验位
- 水泵响应报文(假设实际频率 48.5Hz,电流 3.50A):[05][03][04][01][E5][01][5E][D7][9B]
- 05:从站地址(确认响应)
- 03:功能码(与请求一致)
- 04:返回数据长度(4 字节)
- 01 E5:实际频率(0x01E5=485 → 48.5Hz)
- 01 5E:电流值(0x015E=350 → 3.50A)
- D7 9B:CRC 校验位