一、Modbus协议的规定
1、Modbus协议的特点
(1)Modbus协议使用广泛的原因:
①协议标准开放,且无版权要求。
②协议支持多种电气接口,可以在各种介质上传输。
③消息帧格式简单、紧凑、通俗易懂。
(2)Modbus协议是一种应用层的报文传输协议,它不依赖于硬件总线,允许底层使用任意字节流传输介质,但在工业标准中(截至2026年),官方认可的硬件载体只有串行链路(USART+RS-485)和以太网(TCP/IP)。
2、Modbus协议通信过程
(1)Modbus协议采用主从式通信模型,通常由主设备发起请求,从设备收到请求后才能返回响应。在标准Modbus主从通信模型中,从设备一般不能主动发送数据。

(2)Modbus总线主要定义了请求、响应和数据传输格式,通常不包含复杂的总线仲裁机制。当从机处于忙状态,或没有收到主机的请求时,不会发出响应报文,因此主机需要额外在软件中增加通信状态判断策略,判断请求是否被从机正常接收。
(3)类似于I2C协议,Modbus协议也规定每个从机分配一个唯一的地址,用于区分每个从设备。
(4)Modbus协议的一次数据传输过程:

3、Modbus存储区
(1)Modbus协议对从机定义了存储区,如下所示,其中0区和4区允许主机读写,1区和3区允许主机只读。
|
区号 |
名称 |
主机读写权限 |
地址范围(标准) |
|
0 |
线圈 |
可读可写 |
00001~09999 |
|
1 |
离散输入 |
只读 |
10001~19999 |
|
3 |
输入寄存器 |
只读 |
30001~39999 |
|
4 |
保持寄存器 |
可读可写 |
40001~49999 |
(2)存储区分为线圈/离散输入和寄存器两种,线圈/离散输入存储布尔量(bit,如I/O口的电平高低、外设的开关状态等),寄存器存储16位变量(16bit,如传感器的温度数据、长度不超过16位的密码等)。
(3)Modbus协议对每个存储区划分了地址范围,主机向从机请求数据时,只需要在消息帧中写入数据的起始偏移地址,以及获取数据的长度(单位为字节),从机就会将对应的数据回复主机,类似于I2C协议的指定地址读写。
偏移地址 = 存储区单元地址 - 存储区首地址
比如读取保持寄存器的地址为40999,则偏移地址为40999-40001=998
(4)存储区与从机实际的存储空间相对应,主机访问从机存储区,实际就是访问对应的从机存储空间。

(5)存储器地址分为五位和六位两种,传统的标准地址为五位,也就是上表描述的地址范围,对于新款的设备,协议同时支持扩展地址段,扩展的地址则是六位,如下表所示。
|
区号 |
地址范围(标准) |
地址范围(扩展) |
|
0 |
00001~09999 |
000001~065536 |
|
1 |
10001~19999 |
100001~165536 |
|
3 |
30001~39999 |
300001~365536 |
|
4 |
40001~49999 |
400001~465536 |
4、功能码
(1)对于每个存储区,主机的读写权限是不同的,对任意一个存储区进行读操作或写操作,都可以当作是一个功能,基于这种思想,Modbus定义如下六个功能码:
|
功能码 |
功能说明 |
|
01H |
读取线圈 |
|
02H |
读取离散输入 |
|
03H |
读取保持寄存器 |
|
04H |
读取输入寄存器 |
|
05H |
写入(单个)线圈 |
|
06H |
写入(单个)保持寄存器 |
(2)在实际工程中,往往需要一次性写入多个数据,以上经过排列组合得到的六个功能码,仅支持写入单个存储区单元,为了满足实际工程的需求,Modbus继续定义如下两个功能码:
|
功能码 |
功能说明 |
|
0FH |
写入(多个)线圈 |
|
10H |
写入(多个)保持寄存器 |
(3)实际上,Modbus规定了二十多种功能码(截至2026年),不过常用的功能码只有如上八种,此处不对其它不常用功能码做过多深入介绍。
二、Modbus的三种协议
1、Modbus协议的子类
(1)Modbus协议主要包括如下三类:
|
分类 |
说明 |
|
Modbus RTU |
二进制串行协议,最常用 |
|
Modbus ASCII |
字符型串行协议,较少见 |
|
Modbus TCP |
以太网协议,主要用于以太网 |
(2)严格地说,Modbus协议还包括Modbus UDP、Modbus Plus和Modbus Serial Line/Modbus RTU over TCP这几类,但此处不过多深入讨论
(3)虽然Modbus协议有几种分类,但它们有很多相似之处,以下主要介绍Modbus RTU协议。
2、Modbus RTU协议
(1)Modbus RTU协议的数据帧格式:

①从机地址:长度为1字节,有效范围为1~247,另外255为广播地址(所有从机都接收广播报文)。
②功能码:长度为1字节,关于功能码的定义,在上一节中有介绍。
③数据段:长度不定,数据段的具体定义取决于功能码。
④CRC校验码:长度为2字节(低字节在前),根据从机地址、功能码和数据段的数据计算而得。
(2)Modbus RTU协议不同功能码的数据帧格式:
①读取线圈0x01:
[1]主机发出的数据帧格式如下,需要在数据段交代读取线圈的起始偏移地址和线圈数量,单次0x01读取线圈的数量最多为2000。

[2]从机回复的数据帧格式如下,需要在数据段交代有效数据的字节数,以及主机请求读取的数据。

②读取离散输入0x02:
[1]主机发出的数据帧格式如下,需要在数据段交代读取离散输入的起始偏移地址和输入数量,单次0x02读取输入的数量最多为2000。

[2]从机回复的数据帧格式如下,需要在数据段交代有效数据的字节数,以及主机请求读取的数据。

③读取保持寄存器0x03:
[1]主机发出的数据帧格式如下,需要在数据段交代读取保持寄存器的起始偏移地址和寄存器数量,单次0x03读取寄存器的数量最多为125。

[2]从机回复的数据帧格式如下,需要在数据段交代有效数据的字节数,以及主机请求读取的数据。

④读取输入寄存器0x04:
[1]主机发出的数据帧格式如下,需要在数据段交代读取输入寄存器的起始偏移地址和寄存器数量,单次0x04读取寄存器的数量最多为125。

[2]从机回复的数据帧格式如下,需要在数据段交代有效数据的字节数,以及主机请求读取的数据。

[2]从机原样返回主机发出的数据帧。
⑥写入(单个)保持寄存器0x06:
[1]主机发出的数据帧格式如下,需要在数据段交代写入寄存器的偏移地址和16位数据,1条指令只能写入1个保持寄存器。

[2]从机原样返回主机发出的数据帧。
⑦写入(多个)线圈0x0F:
[1]主机发出的数据帧格式如下,需要在数据段交代写入线圈的起始偏移地址、写入线圈数量、写入数据字节长度以及写入的具体数据,1条指令最多写入1968个线圈。
![]()
[2]从机回复的数据帧格式如下,需要在数据段交代写入线圈的起始偏移地址、写入线圈数量。

⑧写入(多个)保持寄存器0x10:
[1]主机发出的数据帧格式如下,需要在数据段交代写入保持寄存器的起始偏移地址、写入寄存器数量、写入数据字节长度以及写入的具体数据,1条指令最多写入123个保持寄存器。
![]()
[2]从机回复的数据帧格式如下,需要在数据段交代写入保持寄存器的起始偏移地址、写入寄存器数量。

(3)在通信过程中难免会产生异常,对此,Modbus也有设置异常应答机制。
①从机异常应答的通用数据帧格式:

②异常码用于指示异常类型,有如下选择:
|
异常码 |
异常描述 |
|
0x01 |
主机使用非法功能码 |
|
0x02 |
主机请求非法寄存器/线圈地址 |
|
0x03 |
主机请求非法数据长度/写入数值 |
|
0x04 |
从机设备故障 |
|
0x06 |
从机正忙于处理其它命令,无法响应新请求 |
|
0x0A |
网关无法建立到网关目标设备的通信路径(网关专用) |
|
0x0B |
网关目标设备未响应网关的请求(网关专用) |
(4)Modbus RTU对数据帧没有规定帧起始和帧结束标志,需要用时间间隔充当一帧报文的开始标志和结束标志,协议规定开始标志和结束标志的时间都为3.5个字符周期,具体时长与通信波特率有关。
![]()
3、Modbus ASCII协议
(1)Modbus RTU使用二进制(十六进制)表示数据,而Modbus ASCII采用ASCII码表示数据,使用Modbus RTU发送的每一个二进制字节,对应到Modbus ASCII都将拆分为两个ASCII字符发送,两个字符分别对应二进制字节的高4位与低4位,具体对应关系如下:
|
Modbus RTU发送的半字节(4bits) |
Modbus ASCII发送的ASCII码(4bits) |
|
0x0 |
48 |
|
0x1 |
49 |
|
0x2 |
50 |
|
0x3 |
51 |
|
0x4 |
52 |
|
0x5 |
53 |
|
0x6 |
54 |
|
0x7 |
55 |
|
0x8 |
56 |
|
0x9 |
57 |
|
0xA |
65 |
|
0xB |
66 |
|
0xC |
67 |
|
0xD |
68 |
|
0xE |
69 |
|
0xF |
70 |
(2)Modbus ASCII协议的数据帧格式整体与Modbus RTU相似,但额外增加了1Byte起始位CR(0x3A)和2Bytes结束符LF(“\r\n”),校验方式采用LRC(纵向冗长检测,校验的字段不包含起始位)。
![]()
4、Modbus TCP协议
(1)Modbus TCP与Modbus RTU一样,使用二进制(十六进制)表示数据。
(2)Modbus TCP协议的数据帧格式如下:

①Modbus TCP数据帧不需要从机地址。
②Modbus TCP数据帧不需要额外的差错校验,因为TCP属于可靠传输,本身就具有校验差错的能力。
③Modbus TCP数据帧与前面介绍的数据帧相比,增加了长度为7Bytes的MBAP报文头。
(3)MBAP报文头的格式定义如下:

|
字段 |
长度 |
描述 |
客户机定义 |
服务器定义 |
|
事务处理标识箱 |
2Bytes |
Modbus请求/响应事物处理的识别 |
客户机选择 |
拷贝客户机的请求 |
|
协议标识符 |
2Bytes |
0x0000表示使用Modbus协议 |
客户机选择 |
拷贝客户机的请求 |
|
长度 |
2Bytes |
后续所有字节的总长度(包含单元标识符) |
客户机根据请求的数据长度定义 |
服务器根据响应的数据长度定义 |
|
单元标识符 |
1Byte |
串行链路或其它总线上连接的远程从站的识别 |
客户机选择 |
拷贝客户机的请求 |

4万+

被折叠的 条评论
为什么被折叠?



