Modbus RTU · 串行链路协议百科

工控现场最普及的串行通信协议:RS-485 一主多从、轮询问答、帧格式、功能码、CRC 校验。写作用,边看边用。

Modbus RTU RS-485 PLC 串行通信
输入关键词实时过滤下方章节。
一句话总览
先记住最本质的东西。
  • Modbus:1979 年 Modicon(现施耐德电气)发布的公开工业通信协议,应用层标准,物理层可跑串口(RTU/ASCII)或以太网(TCP)。
  • RTU:二进制紧凑编码,一主多从、主站轮询、从站应答;帧 = 地址 + 功能码 + 数据 + CRC16。
  • 工控里几乎遍地都是:PLC ↔ 触摸屏、变频器、仪表、电表、温控器,全靠它。
是什么
协议出身与适用场景。
  • 由 Modicon 公司 1979 年为 PLC 通信设计,后来交给 Modbus 组织维护,完全公开免费,无授权费用。
  • 典型的主从(Master/Slave)模型:一台主站(PLC、上位机、触摸屏)管理最多 247 个从站(地址 1~247;0 是广播地址,只发不收)。
  • 从站不会主动说话,主站问一句、从站答一句(轮询);从站也可以"无响应"表示出错或不在线。
  • 变体:Modbus RTU(二进制,串口主流)、Modbus ASCII(文本,慢但可读)、Modbus TCP(以太网,见另一篇)。
物理层与接线
RTU 通常跑在 RS-485 上,偶尔 RS-232。
RS-485 接线(工业主流)
主站 A ──────── A  从站1  从站2  从站3 ...
主站 B ──────── B  (手拉手菊花链,最远 ~1200m)
GND ────────── GND  (共地,屏蔽层单端接地)

两端各并一个 120Ω 终端电阻(最远的两台设备处)
常用参数(必须全链路一致)
参数常见值说明
波特率9600 / 19200 / 38400 / 115200全链路必须一致,工控默认常为 9600 或 19200
数据位8RTU 固定 8 位
校验位无校验(N)/ 偶校验(E)8N1 或 8E1 最常用;奇校验少见
停止位1 或 2常见 1 位;部分仪表要求 2 位
RS-232(短距离点对点)

电脑串口/调试时用:TX、RX、GND 三线,交叉连接(主机 TX → 从机 RX),距离约 15m 以内,只支持一主一从。

RTU 帧格式
一帧报文长什么样(十六进制字节流)。
请求帧(主站 → 从站):
┌────────┬────────┬──────────────┬──────────┐
│ 地址(1B) │ 功能码(1B) │ 数据区(NB)     │ CRC16(2B) │
└────────┴────────┴──────────────┴──────────┘
  0x01      0x03      起始地址+数量      低字节在前
字段长度说明
从站地址1 字节1~247;0 = 广播(从站执行但不回复)
功能码1 字节告诉从站做什么(读/写、线圈/寄存器)
数据区N 字节请求:起始地址 + 数量 / 写数据;响应:字节数 + 数据
CRC162 字节校验整个帧(地址+功能码+数据),低字节在前发送
帧间隔(RTU 特有的"分包"规则)
  • 帧与帧之间必须静默 ≥3.5 个字符时间(9600bps 下约 4ms)——靠这个判断"上一帧结束、新帧开始"。
  • 帧内相邻字节间隔必须 <1.5 个字符时间,超了会被当成拆帧丢弃。
  • 所以 RTU 不能用"每个字节停顿"的串口助手上位机直发,必须整帧连续发出。
实例:读保持寄存器(功能码 03)
读从站 1 的保持寄存器 0x0000 起 2 个:
请求  01 03 00 00 00 02 C4 0B
      │  │  │     │     └─ CRC16(低字节在前)
      │  │  └─────┴─ 起始地址 0x0000,数量 2
      │  └─ 功能码 03(读保持寄存器)
      └─ 从站地址 1

响应  01 03 04 12 34 56 78 7A 4D
      │  │  │  └─── 4 字节数据:0x1234、0x5678
      │  │  └─ 数据字节数 = 4
      │  └─ 功能码 03(正常应答,最高位为 0)
      └─ 从站地址 1
四种数据模型
Modbus 的世界里只有四种"格子",记住这张表就懂了寻址。
模型位/字读/写功能码PLC 习惯地址典型用途
线圈 Coil1 bit读+写01 读 / 05 写单 / 0F 写多00001 起继电器输出、启停命令
离散输入 Discrete Input1 bit只读0210001 起开关量状态、按钮、限位
输入寄存器 Input Register16 bit只读0430001 起模拟量采集:温度、压力、电流
保持寄存器 Holding Register16 bit读+写03 读 / 06 写单 / 10 写多40001 起设定值、参数、累计量(最常用)
💡
地址换算。报文里用的是从 0 开始的十六进制地址(0x0000~0xFFFF),和 PLC 的 1 起十进制习惯差 1:保持寄存器"40001"在报文里是 0x0000,40002 是 0x0001。各厂家人机/组态软件会自动换算,但写协议时要分清。
💡
大端字节序。16 位寄存器数据一律高字节在前(如 0x1234 发送为 12 34);32 位浮点/长整型顺序看设备手册(AB-CD 或 CD-AB 两种都有,联不上先怀疑这个)。
常用功能码
记住这 8 个就覆盖 95% 应用。
功能码名称请求数据响应
01 (0x01)读线圈起始地址 + 数量字节数 + 位打包数据
02 (0x02)读离散输入起始地址 + 数量字节数 + 位打包数据
03 (0x03)读保持寄存器起始地址 + 数量字节数 + 寄存器数据
04 (0x04)读输入寄存器起始地址 + 数量字节数 + 寄存器数据
05 (0x05)写单个线圈线圈地址 + 0xFF00(ON)/0x0000(OFF)原样回显请求帧
06 (0x06)写单个寄存器寄存器地址 + 数据原样回显请求帧
0F (15)写多个线圈起始地址 + 数量 + 字节数 + 数据起始地址 + 数量
10 (16)写多个寄存器起始地址 + 数量 + 字节数 + 数据起始地址 + 数量
异常响应(功能码最高位置 1 = 出错)
从站把功能码最高位置 1 并附异常码返回,例如请求 03 失败 → 回 83 + 异常码:
01 83 02 C0 F1
   │  │  └─ 异常码 02 = 非法数据地址
   └─ 功能码 0x83 = 0x03 | 0x80(出错标志)
异常码含义排查方向
01非法功能码设备不支持该功能码
02非法数据地址寄存器地址超出设备范围(最常见)
03非法数据值数量/数值非法,或跨了不连续区域
04从站设备故障从站内部错误(如正在写 EEPROM)
06从站忙稍后重试
CRC16 校验算法
RTU 用 CRC-16/MODBUS(多项式 0xA001 反射式),发送时低字节在前。
// 标准实现(C 语言风格):逐字节查表/移位均可,这是逐位算法
uint16_t crc16_modbus(const uint8_t *buf, uint16_t len) {
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < len; i++) {
        crc ^= buf[i];
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x0001) crc = (crc >> 1) ^ 0xA001;
            else              crc >>= 1;
        }
    }
    return crc;   // 发送顺序:低字节在前(crc & 0xFF 先发,再发 crc >> 8)
}
  • 初始值 0xFFFF,多项式(反射)0xA001——这是 Modbus 专用变体,别和通用 CRC16-CCITT(0x1021)搞混。
  • 地址+功能码+数据三部分计算,不包含 CRC 本身。
  • 验证技巧:把"报文 + 它自己的 CRC 低字节 + 高字节"按同样算法再算一遍,结果应为 0x0000
通讯过程
主站如何管理一堆从站。
轮询节奏
  • 主站按"点表"循环发请求:先读 A 仪表 → 等响应(超时)→ 再读 B 变频器 → ...
  • 每轮询一个从站后等待响应或超时,再发下一帧;响应超时典型 100~500ms(按波特率、从站数调)。
  • 从站多、波特率低时,一个完整轮询周期可能几百毫秒~几秒,实时性要求高就别用 Modbus RTU。
常见故障现象
现象大概率原因
全部从站无响应波特率/校验不一致、A/B 接反、共地丢失、主站没发出来
单个从站无响应地址错误、120Ω 终端电阻缺失(远距离)、从站掉电
偶发丢帧/乱码线缆过长无终端电阻、屏蔽层未接地、与变频器/电机强电走同一桥架
功能码 02 异常寄存器地址超范围,查设备点表
数据能读但值不对字节序/浮点序不对、寄存器地址差 1(0 起 vs 1 起)
注意事项
实战经验。
调通顺序。先用串口助手+USB-485 直接对单个从站发帧(01 03 00 00 00 02 的 CRC 可用在线计算器),确认帧格式对,再上上位机/PLC 轮询,少走一半弯路。
用示波器/逻辑分析仪看波形。485 是差分对,A-B 电压:空闲 >200mV、逻辑 1 为 B 高于 A;波形反相说明 A/B 接反。
⚠️
帧间隔是 RTU 的命根子。上位机软件发送时必须在两帧之间留 ≥3.5 字符静默;某些"485 转以太网"模块会拆帧,导致从站不响应——看模块说明是否支持透传/Modbus 网关模式。
⚠️
现场干扰。485 走屏蔽双绞线,屏蔽层单端接地(通常在主站端),远离变频器输出线;实在干扰大再考虑 Modbus TCP 或隔离器。
⚠️
广播地址 0 不回复。想"同时启停全部从站"用 05 功能码发广播,从站执行但不回帧——别傻等响应。
📚 知识库 · Modbus RTU 协议百科 生成于 2026-08-13
没有匹配的内容,换个关键词试试。