3、通信协议基础:Modbus RTU/TCP协议详解

各位同学,咱们今天聊聊通信协议。说实话,搞SCADA这么多年,我见过太多因为协议没选对、没配好,导致现场数据死活读不上来的情况。通信协议就是SCADA系统的“语言”,语言不通,啥都白搭。

这一章,我重点讲三个协议:Modbus RTU/TCP、DNP3,还有OPC UA。前两个是工业现场的老将,第三个是现代化SCADA的新贵。咱们一个一个来。

3.1 Modbus RTU/TCP协议详解

Modbus,这玩意儿太经典了。1979年由Modicon公司发明,到现在40多年了,还在大量使用。为什么?因为它简单、开放、可靠。我在一个水处理项目中,现场几十台PLC全是Modbus RTU,一根双绞线就搞定了所有数据采集,成本极低。

3.1.1 报文结构

Modbus RTU和TCP的报文结构略有不同,但核心思想一致。咱们先看RTU。

Modbus RTU报文结构:

| 地址码 (1字节) | 功能码 (1字节) | 数据区 (N字节) | CRC校验 (2字节) |
  • 地址码:从站地址,范围1-247。0是广播地址。
  • 功能码:告诉从站要干什么。比如读线圈、读寄存器。
  • 数据区:具体参数,比如起始地址、数据数量、具体数值。
  • CRC校验:循环冗余校验,保证数据完整性。这个很重要,现场干扰大的时候,CRC能帮你过滤掉很多错误帧。

Modbus TCP报文结构:

| MBAP头 (7字节) | 功能码 (1字节) | 数据区 (N字节) |
  • MBAP头:包含事务处理标识符、协议标识符、长度、单元标识符。说白了,就是TCP版的“地址码+校验”。
  • 功能码和数据区:和RTU一样。

重要区别:RTU有CRC校验,TCP没有。因为TCP/IP协议栈底层已经做了校验。所以TCP报文比RTU少了2字节的CRC,但多了7字节的MBAP头。

3.1.2 功能码

功能码是Modbus的灵魂。我整理了一张常用功能码表,建议你收藏。

功能码 名称 作用 我常用的场景
01 读线圈状态 读取DO(数字量输出) 读取继电器状态
02 读离散输入 读取DI(数字量输入) 读取按钮、限位开关
03 读保持寄存器 读取AO(模拟量输出)或参数 读取设定值、PID参数
04 读输入寄存器 读取AI(模拟量输入) 读取温度、压力、流量
05 写单个线圈 控制单个DO 启动/停止电机
06 写单个寄存器 控制单个AO或参数 修改设定值
15 写多个线圈 批量控制DO 批量复位报警
16 写多个寄存器 批量控制AO或参数 批量下载配方

我的经验:功能码03和04最容易混淆。记住:03是“保持寄存器”,可读可写;04是“输入寄存器”,只读。现场仪表的数据,比如温度值,通常用04读;PLC内部的设定值,用03读写。

3.1.3 地址映射

地址映射是Modbus最让人头疼的地方。不同厂家的设备,地址定义可能不一样。我踩过不少坑。

Modbus地址通常用5位数字表示,比如40001。第一位数字代表数据类型:

  • 0xxxx:线圈(DO),功能码01、05、15
  • 1xxxx:离散输入(DI),功能码02
  • 3xxxx:输入寄存器(AI),功能码04
  • 4xxxx:保持寄存器(AO/参数),功能码03、06、16

举个例子:地址40001,就是保持寄存器的第1个寄存器。但注意,有些设备地址从0开始,有些从1开始。我曾经在一个项目中,设备手册写的是“寄存器地址40001”,结果我用03功能码读地址0,死活读不到数据。后来才发现,人家内部地址是0,但手册上写的是PLC地址40001。嗯,这里要注意,一定要搞清楚“协议地址”和“PLC地址”的区别。

避坑指南:我曾经在调试一个进口流量计时,按照手册配置了地址40001,结果读回来的数据全是0。折腾了两天,最后发现这个流量计的寄存器地址是“40001”对应的是“协议地址0”,但数据格式是32位浮点数,占用两个寄存器。我读一个寄存器当然读不到完整数据。所以,地址映射不仅要看地址号,还要看数据类型和字节序(大端/小端)。

3.2 DNP3协议简介

DNP3,全称Distributed Network Protocol,分布式网络协议。这玩意儿在电力行业用得特别多。为什么?因为它比Modbus更强大,更适合大规模、高可靠性的SCADA系统。

DNP3的特点:

  • 事件驱动:不是轮询,而是设备主动上报变化。比如开关变位,设备立刻发消息,不用等主站来问。这大大减少了网络流量。
  • 时间戳:每个数据点都带时间戳,方便事后分析。电力系统对时间同步要求极高,DNP3支持精确到毫秒的时间戳。
  • 数据质量:每个数据点都带质量标志,比如“好”、“坏”、“不确定”。主站可以根据质量标志决定是否使用这个数据。
  • 多主站支持:一个设备可以同时和多个主站通信,适合冗余SCADA架构。

我在一个变电站项目中用过DNP3。现场有几十台智能电子设备(IED),全部通过DNP3上报数据。主站只需要监听事件,不用轮询,CPU负载很低。而且,一旦有开关跳闸,IED立刻上报,主站能在50毫秒内收到报警,这个速度Modbus很难做到。

一句话总结:Modbus适合小规模、简单场景;DNP3适合大规模、高可靠性、需要事件驱动的场景,尤其是电力行业。

3.3 OPC UA在现代SCADA中的应用

OPC UA,全称OPC Unified Architecture,统一架构。这是工业通信的未来。为什么这么说?因为OPC UA解决了传统协议(Modbus、DNP3)的很多痛点。

传统协议的痛点:

  • 平台绑定:Modbus依赖串口或TCP,DNP3依赖串口或TCP,都跟硬件绑定。
  • 数据模型简单:Modbus只有寄存器、线圈,没有复杂的数据结构。比如一个“电机”对象,包含转速、温度、状态等多个属性,Modbus没法直接表达。
  • 安全性差:Modbus和DNP3早期版本都没有加密和认证,容易被攻击。

OPC UA的优势:

  • 平台无关:可以在Windows、Linux、嵌入式设备上运行。
  • 丰富的数据模型:支持对象、方法、事件。你可以定义一个“电机”对象,包含“转速”属性、“启动”方法、“过载”事件。这比Modbus的寄存器高级多了。
  • 安全性:支持加密、认证、审计。现在很多工厂要求SCADA系统必须支持OPC UA,因为安全合规。
  • 信息模型:OPC UA可以定义标准的信息模型,比如“PLCopen”、“PackML”。不同厂家的设备,只要遵循同一个信息模型,数据就能互操作。

我最近参与的一个智能工厂项目,全部采用OPC UA。现场有西门子PLC、罗克韦尔PLC、还有各种传感器,全部通过OPC UA接入SCADA。你想想看,以前要写一堆Modbus驱动,现在只需要一个OPC UA客户端,就能读取所有设备的数据。而且,数据是结构化的,比如“电机1.转速”、“电机1.温度”,一目了然。

我的建议:如果你现在要搭建一个新的SCADA系统,优先考虑OPC UA。虽然初期配置比Modbus复杂一点,但后期维护和扩展会轻松很多。尤其是需要对接MES、ERP等上层系统时,OPC UA几乎是唯一的选择。

小结

这一章咱们聊了三个协议:

  • Modbus RTU/TCP:简单、可靠、成本低,适合小规模现场。报文结构、功能码、地址映射是重点。
  • DNP3:事件驱动、时间戳、数据质量,适合电力行业等大规模系统。
  • OPC UA:平台无关、丰富数据模型、安全性高,是现代SCADA的首选。

我个人习惯,在项目初期先评估需求:如果只是采集几个温度、压力,Modbus就够了;如果需要高可靠性和事件上报,选DNP3;如果是新建工厂,直接上OPC UA,一步到位。

下一章,咱们聊聊SCADA系统的硬件选型,包括PLC、RTU、通信网关等。到时候我会分享一些选型时的“潜规则”。


公众号:蓝海资料掘金营,微信deep3321