核心结论
| 协议 | 物理介质 | 能否用通用工具测试 |
|---|---|---|
| Modbus RTU | 串口 (232/485) | ✅ 串口小助手可以,但只能发原始字节 |
| Modbus TCP | 以太网 (网线) | ✅ TCP测试工具可以,但只能发原始数据 |
| Modbus ASCII | 串口 | ✅ 类似RTU,帧格式不同 |
Modbus RTU 详解
报文格式(十六进制字节流)
设备地址\] \[功能码\] \[数据\] \[CRC16校验
1字节 1字节 N字节 2字节
实例:
发送:01 03 00 00 00 03 05 CB
│ │ │ │ └── CRC校验低字节: 0xCB
│ │ │ └──────── 寄存器数量: 3
│ │ └────────────── 起始地址高字节: 0x00
│ └───────────────── 功能码03: 读保持寄存器
└──────────────────── 设备地址: 1
串口小助手设置:
端口: COM3
波特率: 9600 (和设备一致)
数据位: 8
停止位: 1
校验: 无/偶校验 (和设备一致)
发送区(HEX模式): 01 03 00 00 00 03 05 CB
接收区(HEX模式): 会看到原始字节回应
Modbus TCP 详解
报文格式(MBAP头 + PDU)
事务ID\] \[协议ID\] \[长度\] \[单元ID\] \[功能码\] \[数据
2字节 2字节 2字节 1字节 1字节 N字节
实例:
发送:00 01 00 00 00 06 01 03 00 00 00 03
│ │ │ │ │ │ └─ 寄存器数量
│ │ │ │ │ └─────── 起始地址
│ │ │ │ └───────── 功能码03
│ │ │ └──────────── 单元ID(设备地址)
│ │ └────────────────── 后面有6字节
│ └──────────────────────── 协议ID=0 (Modbus)
└────────────────────────────── 事务ID=1
| 工具 | 用途 |
| SocketTool / 网络调试助手 | 发原始TCP数据 |
| Modbus Poll | 专业Modbus工具,解析寄存器 |
| telnet IP 502 | 快速测试端口通不通 |
模式: TCP Client
地址: 192.168.1.100 (PLC/设备IP)
端口: 502
发送(HEX): 00 01 00 00 00 06 01 03 00 00 00 03
接收(HEX): 00 01 00 00 00 09 01 03 06 02 2B 00 00 00 64
在使用Modbus通讯协议时,关于通用工具和专用工具的区别:
| 问题 | 答案 |
|---|---|
| RTU能用串口小助手吗? | ✅ 能,但要手动算CRC、拼字节、解析回应 |
| TCP能用网络调试助手吗? | ✅ 能,但要手动拼MBAP头、解析字节 |
| 为什么还用专用工具? | 专用工具懂协议语义 ,通用工具只传原始字节 |
| 写程序要手动拼字节吗? | ❌ 不需要,用Modbus库(NModbus/EasyModbus) |
一句话:Modbus是"语言",串口/网线是"嘴巴"------你能用任何工具让嘴巴动,但只有懂语言的工具才能明白在说什么。
为什么TCP不需要CRC?
RTU: 地址 + PDU + CRC16
↑ ↑
无MBAP头 需要CRC校验(串口可能丢包/干扰)
TCP: MBAP头 + PDU
↑ ↑
有长度字段 TCP自带校验和+重传机制,无需额外CRC
↑
长度字段=冗余校验,若实际长度不符直接丢弃
| 特性 | Modbus RTU | Modbus TCP |
|---|---|---|
| ADU结构 | 地址+PDU+CRC | MBAP+PDU |
| 地址标识 | 1字节设备地址 | MBAP中的Unit ID |
| 错误校验 | CRC16 | TCP校验+MBAP长度字段 |
| 事务追踪 | ❌ 无 | ✅ 事务ID匹配请求响应 |
| 协议标识 | ❌ 无 | ✅ 可区分Modbus/其他协议 |
| 长度识别 | 通过计时或字节计数 | ✅ MBAP明确指示 |
| 多主站 | ❌ 半双工总线仲裁难 | ✅ TCP天然支持 |
MBAP头是TCP的"信封" (含邮编、发件人、尺寸),PDU是"信纸内容" (功能码+数据),ADU是完整的"信件"。RTU没有信封,直接在信纸上盖章(CRC)就寄了。
Modbus ASCII
关键 :RTU和ASCII都跑在串口硬件 上(232/485),只是帧格式不同;TCP跑在以太网上
| 模式 | 数据格式 | 校验方式 | 效率 | 应用场景 |
|---|---|---|---|---|
| Modbus RTU | 二进制字节 | CRC16 | 高(紧凑) | 工业主流,默认首选 |
| Modbus ASCII | ASCII字符 | LRC校验 | 低(冗长) | 调试可视、低速串口 |
| Modbus TCP | 二进制字节 | TCP校验 | 高(以太网) | 现代网络架构 |
ASCII与RTU的本质区别
| 特性 | Modbus RTU | Modbus ASCII |
|---|---|---|
| 帧头标志 | 3.5个字符时间静默 | : 字符(冒号,0x3A) |
| 数据编码 | 纯二进制 | ASCII十六进制(每个字节拆成2字符) |
| 地址字段 | 1字节 | 2字符(如"01") |
| 功能码 | 1字节 | 2字符(如"03") |
| 数据区 | N字节 | 2×N字符(十六进制字符串) |
| 校验 | CRC16(2字节) | LRC(1字节→2字符) |
| 帧尾 | 3.5个字符时间静默 | CR LF(0x0D 0x0A) |
| 帧长度 | 短(紧凑) | 长(翻倍+开销) |
实例对比:同一请求的RTU vs ASCII
设备地址1,功能码3,读保持寄存器,起始地址0,数量3
RTU帧(二进制,8字节)
十六进制: 01 03 00 00 00 03 05 CB
│ │ │ │ └── CRC16
│ │ │ └── 数量=3
│ │ └── 起始地址=0
│ └── 功能码=03
└── 地址=1
原始字节流: [0x01][0x03][0x00][0x00][0x00][0x03][0x05][0xCB]
└── 不可读,需十六进制工具查看
串口监视器显示 :01 03 00 00 00 03 05 CB(乱码或空白)
ASCII帧(字符,17字节)
字符流: : 0 1 0 3 0 0 0 0 0 0 0 3 F A CR LF
│ └───┬───┘ └───┬───┘ └───────┬───────┘ └───┘ └──┬──┘
│ 地址=1 功能码=03 地址0+数量3 LRC校验 结束
帧头冒号
十六进制字节流:
[0x3A][0x30][0x31][0x30][0x33][0x30][0x30][0x30][0x30][0x30][0x30][0x30][0x33][0x46][0x41][0x0D][0x0A]
人类可读形式: `:010300000003FA` 然后回车换行
串口小助手显示 ::010300000003FA(可直接阅读!)
ASCII的具体编码规则
字节 → ASCII转换
| 原始字节 | ASCII表示 | 计算 |
|---|---|---|
0x01 |
"01" |
高4位=0→'0'(0x30),低4位=1→'1'(0x31) |
0xAB |
"AB" |
高4位=A→'A'(0x41),低4位=B→'B'(0x42) |
0xFF |
"FF" |
都是F→'F'(0x46) |
对比CRC16:LRC是简单累加和,CRC是多项式除法,后者更可靠。
ASCII的优势与劣势
唯一优势:人类可读性
场景:调试现场只有串口小助手/超级终端
RTU显示: □☻ (乱码,看不出内容)
ASCII显示: :010300000003FA (一目了然!)
操作工可以直接抄下报文,用纸笔计算验证。
显著劣势
| 问题 | 说明 | 量化 |
|---|---|---|
| 带宽浪费 | 每个字节变2字符,还要加:和CRLF |
数据量翻倍+3字节开销 |
| 解析延迟 | 必须等CRLF才能确定帧结束 | 实时性差 |
| 传输效率 | 同样波特率,吞吐量约为RTU的1/2 | 9600bps下约480字符/秒 |
| 设备支持 | 现代设备多已取消ASCII支持 | 兼容性问题 |
硬件基础:和RTU完全一致
┌─────────────────────────────────────────┐
│ 应用层:Modbus协议 │
│ (RTU/ASCII/TCP选择帧格式) │
├─────────────────────────────────────────┤
│ 传输层:UART串口时序 │
│ (波特率/数据位/停止位/校验位) │
├─────────────────────────────────────────┤
│ 物理层:RS-232 或 RS-485 │
│ (电气特性、线缆、拓扑) │
└─────────────────────────────────────────┘
↑
ASCII和RTU在这里完全一致!
| 参数 | ASCII模式 | RTU模式 |
|---|---|---|
| 波特率 | 常用9600(可更低,如1200) | 常用9600~115200 |
| 数据位 | 7位或8位(必须7位!) | 8位 |
| 停止位 | 1位 | 1位 |
| 校验 | 偶校验(必须!) | 偶校验/无校验 |
| 流控 | 无 | 无 |
何时还在用ASCII?
| 场景 | 原因 |
|---|---|
| 老旧设备 | 80年代的PLC只支持ASCII |
| 电话线Modem | 早期远程拨号通信,ASCII容错更好 |
| 调试工具 | 某些串口监视器自动解析ASCII模式 |
| 教学演示 | 让学生直观看到报文结构 |
| 特殊网关 | 串口转短信/串口转打印机等低速场景 |
现代工业现状:新项目99%用RTU,以太网普及后用TCP。ASCII基本被淘汰。
Modbus ASCII是用"人类可读字符"包裹的二进制协议,和RTU跑在同一根串口线上,只是把所有字节掰成两半写成十六进制字符串,牺牲了效率换取调试便利。它是Modbus的"明文模式"