Modbus

1 Readme

本文基于Modbus官方文档进行学习。

3 Modbus

在众多学习资料中往往会提到:

Modbus定义了Modbus ASCII、Modbus RTU、Modbus TCP/IP三种基本协议。

但这种看法是不准确的、不本质的
Modbus确实在不同的物理层和链路层上的实现不同,但是这三种情况在应用层的数据封装上完全一致。其主要区别在于:

  • Modbus RTU以逻辑二进制进行数据传输,直接传输Modbus对应的二进制数据包。其主要在串行通信中使用
  • Modbus TCP由于在TCP/IP网络上运行,需要处理网络相关的问题如会话的建立和维持,这由MBAP头部分处理。
  • Modbus ASCII使用ASCII字符来编码二进制数据,每个数据字节被分割为两个ASCII字符。例如使用ASCII字符 '0''F' 编码二进制 0x0F

此外,协议规定Modbus协议是一种请求/应答协议也就意味着无论是哪种Modbus从站均不能主动向主站发送信息

此外,主站也可以被叫作Server,从站被叫作Client。

Modbus当前支持的硬件协议:

  • TCP/IP协议
  • 异步串口协议:
    • RS-232
    • RS-442
    • RS-485
    • 光纤
    • 无线电
  • HDLC(Modbus Plus)

Modbus官方缩写如下表所示。

缩写
含义
ADU Application Data Unit
HDLC High level Data Link Control
HMI Human Machine Interface
IETF Internet Engineering Task Force
I/O Input/Output
IP Internet Protocol
MAC Medium Access Control
MB MODBUS Protocol
MBAP MODBUS Application Protocol
PDU Protocol Data Unit
PLC Programmable Logic Controller
TCP Transport Control Protocol

Modbus提供了一种简单的,可以跨物理层/数据链路层/网络层的通信协议:
chrome_Ylc5HPXvpA.png

3.1 Modbus基本报文结构

Modbus的数据包均遵从如下基本格式:

chrome_1AsQ0QQGM7.png

即:

地址域 功能码 数据域 CRC差错校验
1Byte 1Byte 长度不定,也可能不存在 2Byte

在上图/上表中:

  • ${地址域}${功能码}${数据}${差错校验} 部分被称作ADU(应用数据单元)。
  • ${功能码}${数据} 部分被称作PDU(协议数据单元)。

在通信模型上:

  • Modbus可以分为主站和从站,在一条链路上只能有1个主站但是可以有多个从站
  • 与I2C类似的是,Modbus中也有从站地址寄存器地址的概念。其中,从站地址8位、寄存器地址16位
  • 与C/S模型类似的是,Modbus在任何情况下从站都不会主动发送数据,仅当主站请求时,从站才可以发。
  • Modbus有广播和单拨两种模式
    • 在广播模式下,所有从站必须执行主站命令而无需应答返回
    • 在单播模式下,子节点必须做出应答只有应答完成后主站才可以进行下一个事务处理
    • 和IP协议类似,广播和单播模式通过地址进行区分

在数据结构上,Modbus定义了如下四种基础的数据结构:

数据结构
数据类型 读写类型
附注
离散输入 单bit数据 只读 通常表示 TRUE/FALSEON/OFF
线圈 单bit数据 可读可写
输入寄存器 16bit的字 只读
保持寄存器 16bit的字 可读可写

为了方便叙述,将上述的16bit称之为 "字" ,即 "word" 。但是要注意并不是所有的CPU平台的 "word" 长度均为16bit。

在报文长度上,由于第一版Modbus的实现限制了ADU和PDU的长度(该版本限制ADU最长256字节),因此:

  • RS232、RS485的Modbus中:
    • PDU最长为253字节
    • ADU最长为256字节:
      • Addr=1Byte
      • PDU=253Byte
      • CRC=2Byte
  • TCP中的Modbus中:
    - PDU最长为253字节
    - ADU最长为260字节:
    - MBAP=7Byte
    - Addr=1Byte
    - PDU=253Byte
    - CRC=2Byte
    该设计保证了在任何链路中的数据协议单元长度均为253字节,从而实现了跨物理层/数据链路层/网络层的通信协议。

Modbus在数据编码时采用大端模式

3.1.1 地址域

地址域 功能码 数据域 CRC差错校验
1Byte 1Byte 长度不定,也可能不存在 2Byte

在上述的数据包基本格式中:

  • 地址域共计1Byte,被划分为:
    • 地址 被划分为广播地址
    • 地址 被划分为子节点单独地址
    • 地址 被用作保留地址
      因此:
    • 从机地址范围被定义在
    • 保留区可以用于设置特定地址段的广播指令等

3.1.2 功能码及其对应报文结构

在Modbus中的通信过程中:

  • 如果从站的响应没有错误,则从站返回报文的功能码与主站的请求报文中一致
  • 如果从站的响应发生错误,则从站返回报文的功能码为异常功能码(定义为 请求功能码+0x80 ),具体可见异常响应章节。
地址域 功能码 数据域 CRC差错校验
1Byte 1Byte 长度不定,也可能不存在 2Byte

在上述的数据包基本格式中:

  • 功能码固定为1Byte,其中:
    • 功能码 无效
    • 功能码 作为普通功能码使用
    • 功能码 用于异常响应

Modbus内置的功能码如下:

功能
功能码 操作类型
操作数量
读线圈寄存器 01 单个或多个
读离散线圈寄存器 02 单个或多个
读保持寄存器 03 单个或多个
读输入寄存器 04 单个或多个
写单个线圈寄存器 05 单个
写单个保持寄存器 06 单个
读异常状态 07
诊断 08
读通用事件计数器 0B
获取通用事件日志 0C
写多个线圈寄存器 0F 多个
写多个保持寄存器 10 多个
回报从站地址 11
读文件记录 14
写文件记录 15
使用AND/OR操作寄存器 16
读写多个寄存器 17
读FIFO队列 18
2B
2B/0D
2B/0E

注:

  • 上述表格中常用功能会被标红
3.1.2.1 01H 读线圈寄存器(bit)
3.1.2.1.1 请求报文结构

正如基本规定中所述:

  • Modbus中设备地址占8位、寄存器地址占16位。
  • 01H 读线圈寄存器可以读多个寄存器。
    则有读线圈寄存器的数据包格式为:
格式: 地址域 功能码 起始地址
高字节
起始地址
低字节
读取数量
高字节
读取数量
低字节
CRC校验
Demo: 0x01 0x01 0x02 0xC4 0x01 0x05 2Byte

则上述Demo的含义为:

  • 读取从站地址为 0x01 的设备上的 0x02C4 地址开始的连续 0x0105 个寄存器
3.1.2.1.2 应答报文结构
3.1.2.2 02H 读离散线圈寄存器(bit)

3.2 异常响应

3.3 Modbus On TCP

Modbus TCP默认端口为502端口。