Skip to content

Latest commit

 

History

History
162 lines (114 loc) · 7.58 KB

ModBus.md

File metadata and controls

162 lines (114 loc) · 7.58 KB

简介

Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:* ModbusTCP*。

Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。

标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。

Modbus TCP数据帧

Modbus TCP的数据帧可分为两部分: MBAP+PDU

报文头MBAP

MBAP为报文头,长度为7字节,组成如下:

事务处理标识 协议标识 长度 单元标识符
2字节 2字节 2字节 1字节
内容 解释
事务处理标识 可以理解为报文的序列号,一般每次通信之后就要加1以区分不同的通信数据报文。
协议标识符 0x00 0x00标识Modbus TCP协议
长度 表示接下来的数据长度,单位为字节。
单元标识符 可以理解为设备地址。

帧结构PDU

PDU由 功能码 +数据组成。功能码为1字节,数据长度不定,由具体功能决定。

功能码

Modbus的操作对象有四种:线圈、离散输入、保持寄存器、输入寄存器。

对象 含义
线圈 PLC的输出位,开关量,在Modbus中可读可写
离散量 PLC的输入位,开关量,在Modbus中只读
输入寄存器 PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读
保持寄存器 PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写

根据对象的不同,Modbus的功能码有:

代码 含义 位操作/字操作 操作数量
0x01 读线圈状态 位操作 单个或多个
0x02 读离散输入状态 位操作 单个或多个
0x03 读保持寄存器 字操作 单个或多个
0x04 读输入寄存器 字操作 单个或多个
0x05 写线圈状态 位操作 单个
0x06 写单个保持寄存器 字操作 单个
0x0F 写多个线圈 位操作 多个
0x10 写多个保持寄存器 字操作 多个

Modbus TCP数据帧详细结构

0x01: 读线圈

在从站中读1~2000个连续线圈状态,ON=1,OFF=0

  • 请求:MBAP功能码 起始地址H 起始地址L 数量H 数量L(共12个字节)
  • 响应:MBAP功能码 数据长度 数据(一个地址的数据为1位)
  • 发:在从站0x01中,读取开始地址位0x0002的线圈数据,读0x0008位
    00 01 00 00 00 06 01 01 00 02 00 08
  • 回:数据长度为0x01个字节,数据为0x01,第一个线圈为ON,其余为OFF
    00 01 00 00 00 04 01 01 01 01

0x05:写单个线圈

将从站中的一个输出写成ON或OFF,0xFF00为ON,0x0000为OFF

  • 请求:MBAP功能码 输出地址H 输出地址L 输出值H 输出值L(共12个字节)
  • 响应:MBAP功能码 输出地址H 输出地址L 输出值H 输出值L(共12个字节)
  • 发:将地址为0x0003的线圈设为ON
    00 01 00 00 00 06 01 05 00 03 FF 00
  • 回:写入成功
    00 01 00 00 00 06 01 05 00 03 FF 00

0x02:读离散量输入

从一个从站中读1~2000个连续的离散量输入状态

  • 请求:MBAP功能码 起始地址H 起始地址L 数量H 数量L(共12字节)
  • 响应:MBAP功能码 数据长度 数据(长度:9+ceil(数量/8))
  • 发:从地址0x0000开始读0x0012个离散量输入
    00 01 00 00 00 06 01 02 00 00 00 12
  • 回:数据长度为0x03个字节,数据为0x01 04 00,表示第一个离散量输入和第11个离散量输入为ON,其余为OFF
    00 01 00 00 00 06 01 02 03 01 04 00

0x04:读输入寄存器

从一个远程设备中读1~2000个连续输入寄存器

  • 请求:MBAP功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12个字节)
  • 响应:MBAP功能码 数据长度 寄存器数据(长度:9+寄存器数量*2)
  • 发:读起始地址为0x0002,数量为0x0005的寄存器数据
    00 01 00 00 00 06 01 04 00 02 00 05
  • 回:数据长度为0x0A,第一个寄存器数据为0x0c,其余为0x00
    00 01 00 00 00 0D 01 04 0A 00 0C 00 00 00 00 00 00 00 00

0x03:读保持寄存器

从远程设备中读保持寄存器连续块的内容

  • 请求:MBAP功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12个字节)
  • 响应:MBAP功能码 数据长度 寄存器数据(长度:9+寄存器数量*2)
  • 发:起始地址为0x0000,寄存器数量为0x0003
    00 01 00 00 00 06 01 03 00 00 00 03
  • 回:数据长度为0x06,第一个寄存器的数据为0x21,其余为0x00
    00 01 00 00 00 09 01 03 06 00 21 00 00 00 00

0x06:写单个保持寄存器

在一个远程设备中写一个保持寄存器

  • 请求:MBAP功能码 起始地址H 起始地址L 寄存器值H 寄存器值L(共12个字节)
  • 响应:MBAP功能码 起始地址H 起始地址L 寄存器值H 寄存器值L(共12个字节)
  • 发:向地址为0x0000的寄存器中写入数据0x000A
    00 01 00 00 00 06 00 00 00 0A
  • 回:写入成功
    00 01 00 00 00 06 00 00 00 0A

0x10:写多个保持寄存器

在一个远程设备中写连续寄存器块(1~123个寄存器)

  • 请求:MBAP功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L 字节长度 寄存器值(长度:13+寄存器数量*2)
  • 响应:MBAP功能码 起始地址H 起始地址L 寄存器数量H 寄存器数量L(共12个字节)
  • 发:向起始地址为0x0000,数量为0x0001的寄存器写入数据,数据长度为0x02,数据为0x000F
    00 01 00 00 00 09 01 10 00 00 00 01 02 00 0F
  • 回:写入成功
    00 01 00 00 00 06 01 10 00 00 00 01

ModBus RTU

工作原理

Modbus RTU通信主要基于一个主/从模式,其中一个设备充当主设备(Master),负责发起请求;其他设备作为从设备(Slave),响应主设备的请求。

数据帧

报文格式

从站地址(设备编号) 功能码 数据 校验
1字节 1字节 N字节 2字节

功能码

代码 含义 位操作/字操作 操作数量
0x01 读线圈状态 位操作(1字节) 单个或多个
0x02 读离散输入状态 位操作(1字节) 单个或多个
0x03 读保持寄存器 字操作(2字节) 单个或多个
0x04 读输入寄存器 字操作(2字节) 单个或多个
0x05 写单个线圈 位操作(1字节) 单个
0x06 写单个保持寄存器 字操作(2字节) 单个
0x0F 写多个线圈 位操作(1字节) 多个
0x10 写多个保持寄存器 字操作(2字节) 多个

例,查询从机地址为0x01,线圈寄存器的起始地址为0x0013,结束地址为0x0037。该次查询总共访问37个线圈寄存器。

字节序号 功能 16进制数据
1 从机地址 01
2 功能码 01
3 寄存器起始地址高字节 00
4 寄存器起始地址低字节 13
5 寄存器数量高字节 00
6 寄存器数量低字节 25
7 CRC校验低字节 0C
8 CRC校验高字节 14