文章目录

  • 一、什么是Modbus协议
  • 二、Modbus通信过程
  • 三、Modbus存储区
  • 四、Modbus协议类型
  • 4.1 Modbus RTU协议
  • 4.1.1 Modbus报文帧结构
  • 4.1.2 主机对从机读数据操作
  • 4.1.3 主机对从机写数据操作
  • 4.1.4 10功能码数据解析
  • 4.1.5 总结
  • 4.2 Modbus ACSII协议
  • 4.3 Modbus-TCP
  • 4.4 Modbus-PLUS


一、什么是Modbus协议

Modbus协议是工业控制器网络协议的一种,此协议定义了一个控制器能够认识的消息结构,描述了一个控制器请求访问其他设备、回应来自其他设备以及侦测错误并记录的过程。
Modbus是一种应用层的报文传输协议,它既可以在物理层面上选择串口进行简单的串行通信,也可以使用TCP的方式进行传输。

Modbus的优点
最简单的说,Modbus就是一个总线通信协议,但是他不依赖于硬件总线

  • Modbus协议标准开放、公开发表且无版权要求(免费)
  • Modbus协议支持多种电气接口,包括RS232、RS485、TCP/IP等,还可以在各种介质上传输,如双绞线、光纤、红外、无线等(支持性能好)
  • Modbus协议消息帧格式简单、紧凑、通俗易懂。用户理解和使用简单,厂商容易开发和集成,方便形成工业控制网络(帧格式简单)
    -

二、Modbus通信过程

注意Modbus是一主多从的通信协议
Modbus通信中只有一个设备可以发送请求。其他从设备接收主机发送的数据来进行响应,从机是任何外围设备,如I/O传感器,阀门,网络驱动器,或其他测量类型的设备。从站处理信息和使用Modbus将其数据发送给主站。

也就是说,不能Modbus同步进行通信,主机在同一时间内只能向一个从机发送请求,总线上每次只有一个数据进行传输,即主机发送,从机应答,主机不发送,总线上就没有数据通信。

从机不会自己发送消息给主站,只能回复从主机发送的消息请求。

三、Modbus存储区

从机存储数据必然会存在一个存储区,那就需要文件操作,可以分为只读(-r)和读写(-wr)两种类型

并且存储的数据类型可以分为 :布尔量 和 16位寄存器

  • 布尔量比如IO口的电平高低,灯的开关状态等。
  • 16位寄存器比如 传感器的温度数据,存储的密码等。

Modbus协议规定了4个存储区 分别是0 1 3 4区 其中0区和4区是可读可写,1区和3区是只读。

可通过地址首位数字判断数据所属存储区。
主机向从机获取数据时,只需要告诉从机数据的起始地址、获取多少字节的数据,从机就可以发送数据给主机。

四、Modbus协议类型

Modbus的传输模式也分为三种。包括ASCII、RTU(远程终端控制系统)、TCP三种报文类型

4.1 Modbus RTU协议

4.1.1 Modbus报文帧结构

Modbus报文是指主机发送给从机的一帧数据,其中包含着从机地址,主机想要执行的操作,校验码等内容。

Modbus协议在串行链路上的报文格式如下所示:

Android modbusRTU协议 modulebus协议_网络协议

帧结构 = 从机地址 + 功能吗 + 数据 + 校验

从站地址

功能码

数据

CRC/LRC

1 byte

1 byte

N bytes

2 bytes

  • 从机地址: 每个从机都有唯一地址,占用一个字节,范围0-255,其中有效范围是1-247,其中255是广播地址(广播就是对所有从机发送应答)
  • 功能码: 占用一个字节,功能码的意义就是,知道这个指令是干啥的,比如你可以查询从机的数据,也可以修改从机的数据,所以不同功能码对应不同功能.
  • 数据: 根据功能码不同,有不同功能,比方说功能码是查询从机的数据,这里就是查询数据的地址和查询字节数等。
  • 校验: 在数据传输过程中可能数据会发生错误,CRC检验检测接收的数据是否正确

功能码

功能说明

01

读取线圈状态

02

读取输入状态

03

读取保持寄存器

04

读取输入寄存器

05

写入单线圈

06

写入单寄存器

0F

写入多线圈

10

写入多寄存器

4.1.2 主机对从机读数据操作

主机发送报文格式如下

01 03 00 01 00 01 D5 CA

0x01:从机的地址
0x03:查询功能,读取从机寄存器的数据
0x00 0x01: 代表读取的起始寄存器地址.说明从0x0001开始读取.
0x00 0x01: 查询的寄存器数量为0x0001个Modbus把数据存放在寄存器中,通过查询寄存器来得到不同变量的值,一个寄存器地址对应2字节数据; 寄存器地址对应着从机实际的存储地址,也可以理解为寄存器的长度 0xD5 0xCA: 循环冗余校验 CRC

从机回复报文格式如下

01 03 02 01 17 F8 4A

01:从机的地址
03:查询功能,读取从机寄存器的数据
02: 返回字节数为2个 一个寄存器2个字节
01 17:寄存器的值是0017
F8 4A: 循环冗余校验 CRC

4.1.3 主机对从机写数据操作

主机发送报文格式如下

从站地址

功能码

起始地址(高)

起始地址(低)

数据(高)

数据(低)

校验

0x01

0x06

0x00

0x01

0x00

0x17

0x98 0x04

01:从机的地址
06:修改功能,修改从机寄存器的数据(写入)
00 01: 代表修改的起始寄存器地址.说明修改0x0000-0x0001的存储内容
00 17: 要修改的数据值为0017
98 04: 循环冗余校验 CRC

从机回复报文格式如下

从站地址

功能码

起始地址(高)

起始地址(低)

数据(高)

数据(低)

校验

0x01

0x06

0x00

0x01

0x00

0x17

0x98 0x04

0x01:从机的地址
0x06:写入单个寄存器
0x00 0x01: 代表修改的起始寄存器地址.说明是0x0000
0x00 0x17:修改的值为0017
0x98 0x04: 循环冗余校验 CRC

从机的回复和主机的发送是一样的,如果不一样说明出现了错误

4.1.4 10功能码数据解析

主机发送: 01 10 00 00 00 01 02 11 22 2A 19
从机回复: 01 10 00 00 00 01 01 C9

*发送数据解析*/
01-主机要查的地址
10-功能码,代表修改多个寄存器功能;
00 00-代表修改的起始寄存器地址.说明从0x0000开始.
00 01-代表修改的寄存器数量,这里开始于0x06的修改不同;
02 -表示修改的总字节数,由于只修改了1个寄存器,所以数据要有两个字节;
11 22-表示修改的值,结合上面,就是从第0000寄存器开始修改一个寄存器值为11 22,就是把0000寄存器改为11 22;
2A 19-循环冗余校验,是modbus的校验公式,从首个字节开始到22前面为止;

/*回复解析*/
01-从机返回的地址,说明这就是主机查的从机
10-功能码
00 00-代表修改的起始寄存器地址.说明是0x0000.
00 01-代表修改的寄存器数量,只需要回复这么多久足够了,从机告诉主机,你修改了哪几个寄存器就足够了;
01 C9-循环冗余校验;
4.1.5 总结

modbus RTU协议只需要看懂功能码0x03,0x06,0x10这三个基本的就已经足够了:
03-主机需要发送起始地址+寄存器数量,从机回复总字节数+数据
06-主机发送起始地址+数据内容(因为你只需要修改一个,所以起始地址就是所要修改的地址)从机回复起始地址+数据内容 10-主机发送起始地址+寄存器个数+总字节数+数据从机回复起始地址+寄存器数量

4.2 Modbus ACSII协议

帧形式 对于RTU协议,比如RTU发送一个字节:0x12;
ASCII协议则需要发送2个字节:一个字节代表1,一个代表2,即31和32,才能代表0x12.
所以,acsii协议的效率比较低。

Android modbusRTU协议 modulebus协议_网络协议_02


从上面的图中,看出:

1)比RTU多了起始段 :, 多个结束符CR,LF

2)地址和功能都变成了2个字节;

3)数据部分更加繁琐,但是更符合人们的查看;

由于Modbus-RTU和modbus-ACSII都是基于232和485链路的,所以其通讯模式半双工,一般是主机和从机的模式。其差别就是其字节的格式不同,一个是16进制的数据,一个是acsii数据。
Ascii多了帧头和帧尾,也就是说可以有用这个头尾判断一帧字节来判断是否结束;而RTU没有帧头和帧尾,所以协议里明确两帧之间要大于3.5个字节时间间隔,作为一帧结束的判断依据。

对于RS485来说,总线上一般允许最大32个设备。

4.3 Modbus-TCP

以太网作为介质进行传输,

4.4 Modbus-PLUS

高速令牌传递网络