一、为什么需要Modbus?
在工业控制和嵌入式开发领域,设备之间的通信是核心问题。最直接的方式是使用串口(UART)进行通信,但串口存在一个明显的局限——一个串口硬件只能连接一个设备,当系统需要同时控制多台设备时,串口数量就会成为瓶颈。
解决方案就是引入Modbus协议。Modbus是一套通信协议规范,它定义了设备之间交换数据的规则。在RS485总线上使用Modbus协议,可以实现一主多从的通信架构,一个主设备可以同时管理多达247个从设备,极大地提高了系统的扩展性。
Modbus协议在嵌入式开发中应用广泛,典型场景包括:RS485温湿度变送器、大气压传感器、步进电机控制器、PLC、智能电表等设备的通信与控制。在智能电网领域,Modbus RTU被广泛用于三相电力监控系统,PLC作为中央数据处理和控制单元,通过Modbus RTU与数字功率计通信,实现远程数据采集和可视化。
二、主从架构与通信过程
2.1 单主多从模型
Modbus协议采用单主/多从架构,具有以下核心规则:
同一时刻只能有一个主设备,一个或多个从设备(最多247个)
只能由主设备发起通信请求,从设备不能主动发送数据
从设备之间不能直接通信
主设备必须等一个事务处理完成后,才能发起下一个事务
主设备和从设备之间有两种通信方式:单播模式和广播模式。单播模式中,主设备发送请求后,只有指定地址的从设备会响应;广播模式中,主设备向所有设备发送请求(设备地址为0),所有从设备执行操作但不返回响应。
2.2 事务处理流程
一次完整的Modbus通信事务包括:主设备启动请求 → 从设备执行操作 → 从设备返回响应。如果从设备检测到错误(如非法地址、非法数据值等),则会返回异常响应,异常响应的功能码为原功能码加上128(即最高位置1),并附带一个字节的异常码说明错误原因。
三、数据模型:四种寄存器类型
Modbus协议定义了四种基本的数据类型,理解它们的区别是掌握Modbus的关键。这种划分基于工业控制系统中常见的硬件接口特性和数据访问需求,通过将数据按照功能、读写属性和物理意义进行分类,为不同厂商设备之间的互操作性提供了清晰一致的数据模型基础。
| 数据类型 | 中文别名 | 存储单元 | 访问权限 | 典型用途 |
|---|---|---|---|---|
| 线圈(Coils) | 数字输出/DO | 1 bit | 可读可写 | 控制继电器、开关、指示灯 |
| 离散输入 | 数字输入/DI | 1 bit | 只读 | 读取限位开关、按钮状态 |
| 输入寄存器 | 模拟量输入/AI | 16 bit | 只读 | 读取传感器测量值 |
| 保持寄存器 | 模拟量输出/AO | 16 bit | 可读可写 | 存储配置参数、设定值 |
线圈用于控制数字输出设备,例如通过线圈寄存器控制电磁阀的开或关。离散输入则相当于线圈的只读模式,用于读取拨码开关的开关状态等。保持寄存器用于存储可读写的模拟量数据,如步进电机控制器中控制电机旋转角度的寄存器。输入寄存器只能读取不能写入,通常用于读取模拟量输入,如温度、压力等传感器数据。
在实际应用中,PLC地址与Modbus协议地址之间存在对应关系。PLC地址通常以1为起始(如40001),而Modbus协议地址以0为起始(如0000H),两者之间存在偏移。不过很多Modbus设备的数据手册已经详细说明了各寄存器的地址,实际开发中直接参考设备手册即可。
四、帧结构详解
4.1 通用帧结构
Modbus的PDU(协议数据单元)由功能码和数据组成,这是数据帧最核心的内容。在PDU基础上添加地址域(前缀)和差错校验(后缀),就构成了完整的ADU(应用数据单元)。
4.2 RTU模式
RTU(远程终端单元)模式是工业现场最常用的帧格式。每一帧的时间间隔至少为3.5个字符时间,同一帧内两个字符之间的间隔不能超过1.5个字符时间,否则整个报文将被丢弃。帧结构为:
[从设备地址(1字节)][功能码(1字节)][数据(N字节)][CRC校验(2字节)]
CRC-16校验使用多项式 216+215+22+1216+215+22+1 进行计算,纠错能力强。在9600bps波特率下,3.5个字符时间约为4.01ms。
4.3 ASCII模式
ASCII模式将每个8位字节数据用两个ASCII字符表示。例如,数据0x5B就用字符‘5’(ASCII码0x35)和‘B’(ASCII码0x42)传输。帧格式为:
: [地址][功能码][数据][LRC校验][CR LF]
ASCII模式的优点是更容易调试,但传输效率较低,适合与ASCII码相关的设备通信。
4.4 TCP模式
Modbus TCP在工业以太网中使用,帧结构为MBAP头(7字节)+ PDU。MBAP头包含事务标识、协议标识、长度和单元标识。由于TCP协议本身提供了可靠的传输保证,Modbus TCP不需要额外的CRC校验。
4.5 关于字节序
Modbus协议本身不指定使用大端序还是小端序。在RTU模式下常使用小端序来表示寄存器地址和数据,而寄存器内部的多字节数据通常采用大端序(高字节在前)。
五、常用功能码详解
功能码占用1个字节,范围1~127。如果出现异常,从设备返回的异常响应中功能码最高位置1(加128),因此异常码范围为129~255。
以下是最常用的公共功能码及其操作方式:
| 代码 | 名称 | 操作类型 | 操作数量 | 寄存器类型 |
|---|---|---|---|---|
| 01 | 读线圈状态 | 位操作 | 单个或多个 | 线圈 |
| 02 | 读离散输入状态 | 位操作 | 单个或多个 | 离散输入 |
| 03 | 读保持寄存器 | 字操作 | 单个或多个 | 保持寄存器 |
| 04 | 读输入寄存器 | 字操作 | 单个或多个 | 输入寄存器 |
| 05 | 写单个线圈 | 位操作 | 单个 | 线圈 |
| 06 | 写单个保持寄存器 | 字操作 | 单个 | 保持寄存器 |
| 15 | 写多个线圈 | 位操作 | 多个 | 线圈 |
| 16 | 写多个保持寄存器 | 字操作 | 多个 | 保持寄存器 |
位操作的最小单位是1位(bit),字操作的最小单位是2个字节(16位)。功能码03用于读取保持寄存器中的持久性数据,功能码04用于读取输入寄存器中的模拟量测量值,功能码06用于向从站写入单个保持寄存器,功能码16则支持批量写入多个寄存器。
5.1 功能码01实例:读线圈状态
假设需要读取设备地址为3的从设备,线圈地址为19到55(共37个状态):
查询报文(RTU模式):0x03 0x01 0x00 0x13 0x00 0x25 [CRC校验]
其中0x0013 = 19(起始地址),0x0025 = 37(寄存器数量)。
响应报文:
从设备将37个状态值按位打包,每8位组成一个字节,最后不满8位的用0填充。假设状态值为:ON ON OFF OFF ON OFF ON OFF,对应的字节为1100 1010,由于Modbus采用低位在前的传输顺序,实际对应数据为0101 0011,即0x53。因此响应报文为:
0x03 0x01 0x05 0x53 0x6B 0x01 0xF4 0x1B [CRC校验]
其中0x05表示数据域长度为5个字节。
5.2 功能码02实例:读离散输入状态
类似地,读取设备地址为3、寄存器地址为100~119的离散输入状态(共20个):
查询报文:0x03 0x02 0x00 0x64 0x00 0x14 [CRC]
响应报文:0x03 0x02 0x03 0x53 0x6B 0x01 [CRC]
功能码02与功能码01的主要区别在于操作的是只读的离散输入寄存器,不能执行写操作。
六、通信机制深入
6.1 地址域
地址域表示从设备的地址,范围为1~247。广播地址为0。从设备发送响应包时,地址保持不变。ASCII模式中地址占2个字节,RTU模式中占1个字节。主设备本身不使用设备地址。
6.2 数据域
数据域的具体内容取决于功能码,以字节为单位,长度可变。对于某些功能码,数据域可以为空。例如功能码03的数据域包含寄存器起始地址和寄存器数量,而响应报文的数据域则包含字节数和寄存器数据。
6.3 校验域
ASCII模式:使用LRC(纵向冗余校验),校验内容不包含帧头(冒号)和帧尾(回车换行),实际校验内容只有1个字节
RTU模式:使用CRC-16(循环冗余校验),对整个报文进行校验,纠错能力强
TCP模式:不需要额外的校验域,由TCP协议保证传输可靠性
七、异常处理机制
当Modbus设备无法处理请求时,会返回异常响应而非预期的数据。异常响应是Modbus协议唯一的错误报告机制,理解它对于诊断地址错误、不支持的功能码等问题至关重要。
异常响应的格式为:从设备将请求中的功能码加上0x80(最高位置1),然后附加一个字节的异常码。例如,主设备发送功能码0x03(读保持寄存器),如果从设备不支持该功能码,则返回0x83和异常码0x01。
主要异常码包括:
| 异常码 | 名称 | 说明 |
|---|---|---|
| 01 | 非法功能 | 设备不支持请求的功能码 |
| 02 | 非法数据地址 | 请求的寄存器地址不存在 |
| 03 | 非法数据值 | 请求的值超出允许范围 |
| 04 | 从设备故障 | 处理请求时发生不可恢复错误 |
| 05 | 确认 | 设备已接受请求,需要更长时间处理 |
| 06 | 从设备忙 | 设备正在处理长耗时命令,请稍后重试 |
| 0A | 网关路径不可用 | 网关无法连接到目标设备 |
| 0B | 网关目标设备无响应 | 目标设备在规定时间内未响应 |
根据Chipkin对437个以上Modbus集成项目的统计,异常码02(非法数据地址)占所有异常的约50%,最常见的根本原因是地址偏移错误或寄存器约定不一致。
八、开发实践:虚拟串口与仿真调试
在Modbus开发过程中,通常需要搭建仿真环境进行调试。
8.1 虚拟串口配置
使用Virtual Serial Port Driver(VSPD)软件可以“虚拟”出多个串口设备。在开发过程中,添加虚拟串口COM3和COM4,它们之间形成虚拟连接,模拟一条串口线,用于开发调试。仅在开发中使用虚拟串口,实际部署时使用真实的串口设备。
8.2 Modbus Slave与Modbus Poll
Modbus Slave:模拟从站设备。配置从站地址、功能码、寄存器地址和数量,可以手动设置各寄存器的值(支持Hex、Decimal等格式)。
Modbus Poll:模拟主站设备。配置读写请求,查看从站返回的数据。
两者配合使用,可以完整模拟主从通信过程。通过Communication Traffic窗口,可以实时查看发送和接收的原始报文,便于调试分析。
8.3 工业现场部署
在实际工业场景中,Modbus RTU over TCP是一种常见的部署方式。由于工业现场大量设备使用RS485串口通信,而现代监控系统通常基于以太网,因此需要通过串口服务器或Modbus网关进行协议转换。例如在变电站在线监控系统中,现场变压器采用Modbus RTU协议通过RS485总线连接,通过Modbus网关将RTU数据转换为TCP协议接入变电站监控系统,实现实时数据监控。
在制药企业的数据采集系统中,通过7台边缘网关采集空调系统、空压机、纯水机等设备的运行参数,边缘网关作为Modbus TCP从站(端口502),云网关作为主站采集数据上传至云平台。
九、典型行业应用案例
9.1 变电站在线监控
某数据中心机房需要对环境参数进行实时监控,现场已部署温湿度传感器、水浸传感器及UPS状态监测装置,这些末端传感器均采用Modbus RTU串口通信协议通过RS485总线连接。通过Modbus网关将RTU设备的数据转换为Modbus TCP,接入TCP/IP网络实现变压器设备与变电站监控系统的数据交互。该方案需要具备较强的抗电磁干扰性,适用于恶劣的现场环境,并支持Modbus RTU到Modbus TCP的转换。
9.2 智能制造中的电力监控
在泰国某棕榈油制造厂,通过Modbus RTU协议将三相智能电表与电表集中器连接,读取榨油机马达的电力信息,进行电力数据的储存,并通过Modbus TCP协议传送到后端的SCADA软件进行数据整合。通过分析不同电流下的负载状况(未运作、中负载、高负载),客户可以提前安排机台保养时程,达到预知保养的目的。该方案有效为客户增加28%的棕榈油产能,并去除了以往人力监控的盲点。
9.3 制药行业数据采集
在制药企业中,数据采集系统通过7台边缘网关采集空调系统、空压机、纯水机、冷冻机等设备的运行参数数据及运行状态。在边缘网关上创建转发,通过Modbus TCP协议,边缘网关作为从站(端口502),通过设备地址区分,将采集的设备数据上传至云平台。云网关作为主站,通过Modbus TCP协议采集从边缘网关传输的设备数据,实现了工业设备数据的云端汇聚。
十、总结
Modbus协议经过四十多年的发展,已成为工业自动化领域事实上的通信标准。它的核心设计理念——简洁的PDU结构、清晰的数据模型、灵活的主从架构——使其在从串口到以太网、从简单传感器到复杂PLC的各种场景中都能适用。
掌握Modbus协议的关键在于理解以下几点:四种寄存器类型的区别和用途、RTU/ASCII/TCP三种帧格式的差异、常用功能码的请求与响应结构,以及异常处理机制。在实际开发中,虚拟串口和Modbus仿真工具是重要的调试手段,而Modbus网关则是将传统串口设备接入现代工业以太网的关键桥梁。