当前位置: 首页 > 网络知识

ModbusTCP协议简介与编程流程图

时间:2026-01-29 09:26:48

  本文主要目的是为了写一个简单的ModbusTCP服务器客户端程序而记录的知识点,里面包含了编程所需要的必要背景知识和协议解析流程图。

Modbus基本数据类型
  Modbus有四种基本数据类型:

ModbusTCP数据格式
  一个正常的ModbusTCP数据帧包括以下三部分:

  这三部分合称为ADU,也就是应用数据单元,其中功能码和数据合称为PDU,也就是协议数据单元。ADU中的MBAP(MODBUS Application Protocol)是ModbusTCP特有的内容。PDU在所有Modbus中格式完全相同。
  ModbusTCP数据帧使用端口502发送,端口502是互联网组织专门为MODBUSTCP协议保留的端口号。

MBAP报文头格式:
  MBAP报文头(MODBUS协议报文头)共7个字节,其含义如下:

PDU格式
  由于不同功能码对应着不同的数据格式,因此需要将功能码和数据部分一起阐释,我这里只介绍我的程序将要涉及到的功能码3和16。之所以只选择了这两个功能码,是由于这两个功能码基本上就可以涵盖数据采集相关的所有功能,写多个寄存器可以设置采集参数、DA输出、设置开关量输出……读多个寄存器可以读取各种采集结果。

03 (0x03)读保持寄存器

  每个寄存器的宽度是16位,2个字节,由于是大端模式(Bigendian),因此高字节在前,低字节在后,其具体数据格式如下:
请求:

功能码1个字节3(0x03)
起始地址 2个字节 0~65535(0xFFFFF)
寄存器数量 2个字节 N=1~125(0x7D)
响应:
功能码1个字节3(0x03)
字节数 1个字节 N*2
寄存器值 N*2个字节

举例:
下列是请求读地址偏移0一个寄存器的值,寄存器值是0
字节序号(10进制):00 01 02 03 04 05 06 07 08 09 10 11
发送字符(16进制):00 00 00 00 00 06 00 03 00 00 00 01
接受字符(16进制):00 00 00 00 00 05 00 03 02 00 00

寄存器数量是受限于MODBUSRTU的协议数据帧(PDU)长度不能超过252,PDU中的功能码和字节数占用两个字节,因此(2522)/2=125

读保持寄存器流程图

16 (0x10)写保持寄存器
  写保持寄存器是读多个寄存器的反向操作,它可以与读多个寄存器是同一个功能项的读写操作,也可以是不同功能项的单独操作。例如在DA(数模转换)中,使用写多个寄存器设置DA输出值,然后可以用读多个寄存器返回之前设定的值。也可以相同的地址,返回AD(模数转换)的采集值,这取决于实际应用。其具体格式如下:
请求:

功能码1个字节16(0x10)
起始地址 2个字节 0~65535(0xFFFFF)
寄存器数量 2个字节 N=1~123(0x7B)
字节数 1个字节 2*N
寄存器值 N*2个字节 大端排列的值

PDU最大字节数为252,减去功能码,起始地址,寄存器数量,字节数所占用的6个字节为246,因此寄存器数量最大为123。

响应:

功能码1个字节16(0x10)
起始地址 2个字节 与请求起始地址相同
寄存器数量 2个字节 N

举例:
下列是请求写地址偏移0一个寄存器的值,寄存器值是0
字节序号(10进制):00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
发送字符(16进制):00 00 00 00 00 09 00 10 00 00 00 01 02 00 00
接受字符(16进制):00 00 00 00 00 06 00 10 00 00 00 01

写多个寄存器流程图:

异常响应

  当请求失败的时候,服务器将会返回异常响应,异常响应帧会在功能码的位置将原有功能码+0x80,后面的数据是异常码,其具体格式如下:
异常响应:

功能码1个字节0x80+请求功能码
异常码    1个字节   常用异常码:
01:不支持的功能码
02:地址错误,起始地址+寄存器数量如果超范围,也属于地址错误
03:数据错误,这里的数据还包括了PDU数据本身,比如请求的寄存器数量超过了PDU所允许的最大长度。
04:从站故障,在服务器处理请求过程中遇到了错误。

MODBUSTCP请求响应流程
  服务器在接收到客户端请求后,首先判断协议标识符,如果是MODBUS协议,才能继续处理,然后根据MBAP报文头中的后续字节数来拆出一个完整的数据帧。如果客户端是使用请求响应方式来发送请求,则服务器接收到的每包数据都应该是且只有一个完整的数据包。最后根据功能码来将请求交给各个功能码子程序来处理。流程图如下:



上一篇:Qt 使用 Visual Leak Detector(方式二)
下一篇:C++ 快速清空vector以及释放vector内存
Modbus
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素