Modbus通讯协议详解
00 分钟
2023-12-28
2024-4-6
type
status
date
slug
summary
tags
category
icon
password
文章筛选

一、协议的基本特点

Modbus是施耐德电气于1979年为使用PLC通信而发表的一种串行通信协议。现在它已经成为工业领域通信协议的业界标准,并且是工业电子设备之间常用的连接方式。
Modbus通信协议作用在OSI模型的物理层(1层)、数据链路层(2层)及应用层(7层)。这里的OSI被称为开放系统互联参考模型,它定义了网络互连的七层框架,每层框架都有其各自的通信协议。
notion image
MODBUS协议是一种 主从式 串行异步 半双工 通信协议。
主从式 指通信设备中有一台主机和多台从机(最大约240个),主机可以和从站双向通信,可以和单独一个从站通信,或者所有从站同时通信(广播),这个时候不需要回应。而从站只能和主站通信,从站之间不能相互通信,从机也不会主动给主机发送信息,只会应答主机。
notion image

二、Modbus数据模型及其功能码

 
寄存器种类
读写状态
位操作字操作
适用功能码
Modbus地址编号
线圈寄存器
读/写
单个比特
01H(读); 05H(写单个位); 0FH(写多个位)
0
离散输入寄存器
只读
单个比特
02H
1
输入寄存器
只读
俩个字节
04H
3
保持寄存器
读/写
俩个字节
03H(读); 06H(写单个字节); 10H(写多个字节)
4
💡
线圈寄存器:实际上就可以类比为开关量(继电器状态),每一个bit对应一个信号的开关状态。所以一个字节就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。对应上面的功能码也就是:0x01 0x05 0x0f
离散输入寄存器:如果线圈寄存器理解了这个自然也明白了。离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。所以功能码也简单就一个读的 0x02
保持寄存器:这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。一般对应参数设置,比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写,所以功能码有对应的三个:0x03 0x06 0x10
输入寄存器:这个和保持寄存器类似,但是也是只支持读而不能写,一般是读取各种实时数据。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值。对应的功能码也就一个 0x04
notion image
功能码
名称
数据类型
作用
0x01
读线圈寄存器
取得一组逻辑线圈的当前状态(ON/OFF )
0x02
读离散输入寄存器
取得一组开关输入的当前状态(ON/OFF )
0x03
读保持寄存器
整型、浮点型、字符型
在一个或多个保持寄存器中取得当前的二进制值
0x04
读输入寄存器
整型、浮点型
在一个或多个输入寄存器中取得当前的二进制值
0x05
写单个线圈寄存器
强置一个逻辑线圈的通断状态
0x06
写单个保持寄存器
整型、浮点型、字符型
把具体二进值装入一个保持寄存器
0x0f
写多个线圈寄存器
强置一串连续逻辑线圈的通断
0x10
写多个保持寄存器
整型、浮点型、字符型
把具体的二进制值装入一串连续的保持寄存器

三、Modbus报文说明

1、主机发送报文格式

从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
从站地址也就是地址域,首先看地址域部分。它是由一个8位字节构成,那么理论上可以有256个不同的地址。这是否意味我们可以为主站连接256个从站设备呢?答案是否定的。因为在这256个地址空间中又有以下这些区别。Modbus规定地址0保留为广播地址1~247为子节点单独地址248~255为保留地址。所以从机的地址范围在1~247之间,而其他地址可以由用户自由扩展。这样就可以在满足用户特定需求的同时尽量保持协议的兼容性。当然,保留区也具有同样的功能,如设置特定地址段的广播指令等等。需要注意的是地址域只和从站有关,主站是没有地址标识的,而且每个从站的地址都是唯一的,以便于与其它从站区别。
notion image

2、从机响应报文格式

从站地址
功能码
返回字节数
data1(字节数是多少,这里就有多少个数据)
CRC校验低8位
CRC校验高8位

.MODBUS功能码实例

(一)线圈寄存器(0区)的读写

1、读线圈寄存器:功能码01

读单个位
假设0区寄存器0-9的值分别位:0100 0000 01
①主机发送:(读取第二位的值)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x01
0x00
0x01(即读取第二位的值)
0x00
0x01
0xAC 0x0A
从机应答:
从站地址
功能码
返回字节数
data1
CRC校验
0x01
0x01
0x01
0x01
0x90 0x48
也就是说从机返回1个字节的数据,数据值为1,正确的读到了寄存器的值
 
仿真结果如下:
notion image
②主机发送(读取第10位)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x01
0x00
0x09(即读取第10位的值)
0x00
0x01
0x2D 0xC8
从机应答:
从站地址
功能码
返回字节数
data1
CRC校验
0x01
0x01
0x01
0x01
0x90 0x48
仿真结果如下:
notion image
读取多个位
假设0区寄存器0-9的值分别位:0100 0110 01
①主机发送:(读取10位
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x01
0x00
0x00
0x00
0x0A(读取数量共10位)
0xBC 0x0D
从机应答:
从站地址
功能码
返回字节数
data1
data2
CRC校验
0x01
0x01
0x02
0x62(这个是数据的低字节)
0x02(这个数据的高字节)
0x11 0x5D
💡
注:返回的数据含有多个字节,其低字节在前,高字节在后
仿真结果如下:
notion image
②主机发送:(读取第6、7位
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x01
0x00
0x05(从第六位开始)
0x00
0x02(读取数量共2位)
0xBC 0x0D
从机应答:
从站地址
功能码
返回字节数
data1
CRC校验
0x01
0x01
0x01
0x03
0x11 0x89
仿真结果如下:
notion image

2、写入线圈寄存器:功能码:05(写入单个)功能码:0F(写入多个)

功能码:05(写入单个)
假设0区寄存器0-9的值分别位:0100 0010 01
①主机发送(第六位写为1)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
data1
data1
CRC校验
0x01
0x05
0x00
0x05(数据的第六位)
0xFF
0x00
0x9C 0x3B
💡
注:写0xf 0x00表示设置线圈状态为ON,写0x00 0x00表示设置线圈状态为OFF
从机应答:与主机发送内容一模一样
仿真结果如下:
notion image
②主机发送(第十位写为0)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
data1
data1
CRC校验
0x01
0x05
0x00
0x09(数据的第十位)
0x00
0x00
0x1D 0xC8
💡
注:写0xf 0x00表示设置线圈状态为ON,写0x00 0x00表示设置线圈状态为OFF
从机应答:与主机发送内容一模一样
仿真结果如下:
notion image
功能码:0F(写入多个)
假设0区寄存器0-9的值分别位:0000 0001 11
①主机发送(第三位和第五位写1,第4位写0)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
字节数
data1
CRC校验
0x01
0x0F
0x00
0x02
0x00
0x03
01
05 (第三位和第五位写1,第四位写0)
0x36 0x94
💡
注:置1的线圈,它所对应的为一,最终组成的二进制转化位16进制写入data
从机应答:与主机发送内容一样,就是没有字节数和data
仿真结果如下:
notion image
②主机发送(第七到十位分别写如1010)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
字节数
data1
CRC校验
0x01
0x0F
0x00
0x06
0x00
0x04
01
05
0x76 0x95
从机应答:与主机发送内容一样,就是没有字节数和data
notion image

(二)离散输入寄存器(1区)的读取

功能码:02

读离散输入寄存器,位操作,可读单个或多个,协议类似功能码0X01协议
 

(三)输入寄存器(3区)的读取

功能码:04

1)描述:读输入寄存器,字节指令操作,可读单个或者多个;
2)发送指令:同03H;
3)响应:同03H;
详见:下文

(四)保持寄存器(4区)的读写

1、读保持寄存器:功能码03

这个功能码和01类似,只是返回的数据,一位要用俩个字节
读取单个
主机发送(读取第五位)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x03
0x00
0x04(读取第5位)
0x00
0x01
0xC5 0xCB
从机应答:
从站地址
功能码
返回字节数
data1
data2
CRC校验
0x01
0x03
0x02
0x00
0xFF
0xF8 0x04
💡
注:一个数据返回俩个字节
仿真结果如下:
notion image
读取多个
主机发送:(读取第三位至第五位)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
CRC校验
0x01
0x03
0x00
0x02(从第3位开始)
0x00
0x03(一共读取三位)
0xA4 0x0B
从机应答:
从站地址
功能码
返回字节数
data1高8位
data1低8位
data2高8位
data2低8位
data3高8位
data3低8位
CRC校验
0x01
0x03
0x06
0x00
0x78
0x00
0x00
0x00
0xFF
0xC1 0x3F
💡
注:一个数据返回俩个字节,一共读取三个数,则返回6个字节
仿真结果如下:
notion image

2、写保持寄存器(功能码06(写单个)功能码10(写多个))

写单个:功能码06
主机发送:(将第三个的值变为566:即高八位为0x02 低八位为0x36)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
data1
data1
CRC校验
0x01
0x06
0x00
0x02(数据写入第三位)
0x02
0x36
0xA9 0x1D
从机响应和主机内容一样
notion image
写多个:功能码10
①主机发送(第三个到第五个分别写入:255 26 393)
从站地址
功能码
寄存器起始地址高8位
寄存器起始地址低8位
寄存器数高八位
寄存器数低八位
字节数
data1高8位
data1低八位
data2高8位
data2低8位
data3高8位
data3低8位
CRC校验
0x01
0x10
0x00
0x02
0x00
0x03
0x06
0x00
0xFF
0x00
0x1A
0x03
0xE4
0x72 0x22
💡
注:写入一个需要用俩个字节,这里写入3个,则需要6个字节
从机应答:与主机发送内容一样,就是没有字节数和data
仿真结果如下:
notion image

注:串口、RS232、RS485的区别

TTL
RS232
RS485
传输规范
计算机处理器控制的设备内部各部分之间通信的标准技术
异步串口协议
半双工同步协议
传输距离
1m
15m
1200m
传输速率
常见波特率范围
可达2Mbps(19200)
可达10Mbps
电气特性
0V ~ 5V
逻辑 1:-15V ~ -3V 逻辑0:+3V ~ +15V
逻辑 0:-6V ~ -2V 逻辑 1:+2V ~ +6V
网络拓扑结构
单向通信或点对点连接
单向通信或点对点连接
多个设备在同一条总线上进行主从通信
频率
2M
50M
notion image
notion image
notion image
 
MCGS 串口父设备串口号设置为COM2 为RS485通讯 7接A 8接B
 

评论
  • Waline