一、协议概述
Modbus协议是应用于电子控制器上的一种通用语言,通过此协议,控制器相互之间、控制器经由网络和其它设备之间可以通信,设计modbus初衷就是为了让不同厂商生产的控制设备可以连成工业网络,进行集中控制。它是一种请求——应答方式的协议。
二、Modbus报文模型
Modbus协议定义了一个简单的协议数据单元(PDU),它独立于底层通讯。在应用数据单元(ADU)上,Modbus印象可以导入一些附加的数据区域。
Modbus应用数据单元被发动Modbus通讯的客户端创建,所完成的功能是指出到服务器将要完成什么动作。Modbus协议是客户端建立的请求格式。
Modbus的协议数据单元中的功能码域,由一个字节组成。有效的范围是1—255,但128—255的范围是被保留的。当信息从客户端传送到服务器时,功能码负责告知服务器将执行什么动作。功能码“0”是无效的。
三、两种传输方式
1.ASCII模式(美国标准信息交换代码)
-
消息中每个8bit都作为两个ASCII字符发送
-
1个起始位,7个数据位,1个奇偶校验位和一个停止位或者两个停止位
-
报文检测是LRC校验(纵向冗余校验)
-
字符发送的时间间隔可达到1S而不产生错误
2. RTU模式(远程终端单元)
-
消息中每个8bit字节包含两个4Bit的十六进制字符,因此,在波特率相同的情况下,传输效率比ascii大
-
1个起始位,8个数据位,1个奇偶校验位和一个停止位或者两个停止位
-
报文检测是CRC校验(循环冗余校验)
-
消息发送至少要以3.5个字符时间的停顿间隔开始,整个消息帧必须作为一连续的流传输,整个数据帧在传输中有超过1.5个字符时间的停顿时间,接收设备将刷新不完整的信息帧并认为存在数据丢包现象。(波特率9600时,3.5个字符时间大概是4ms)
因为ASCII协议的可读性强,但传输效率低,导致工业现场很少用。
四、报文格式
读数据:
下行报文:
从机地址 | 功能码 | 寄存器起始地址高字节 | 寄存器起始地址低字节 | 读取寄存器个数高字节 | 读取寄存器个数低字节 | CRC校验低 | CRC校验高 |
上行报文:
从机地址 | 功能码 | 返回字节个数 | 寄存器数据 | CRC校验 |
写数据:
下行报文:
从机地址 | 功能码 | 寄存器起始地址 | 写寄存器个数 | 要写的数据 | CRC校验 |
上行报文:
从机地址 | 功能码 | 寄存器起始地址 | 写寄存器个数 | 写入的数据 | CRC校验 |
1、从机地址范围:1~247,“0”为广播地址,占一个字节。
2、功能码是信息帧的第二个字节。定义功能号是1~255,占一个字节,具体参见modbus中文第10页开始。
3、modbus存储区(寄存器起始地址)
寄存器起始地址占两个字节,高字节在前,低字节在后。
Modbus协议中数据模型常用的有两种,带有4个独立块的modbus数据模型和仅有1个块的modbus数据模型,对于不同的数据模型参数地址的编制不同,一般采用1个块的modbus数据模型,如下:
存储区标识 | 名称 | 类型 | 读/写 | 存储单元地址 | 常用为 |
0XXXX | 线圈 | 位 | 读/写 | 00001~0FFFF | DO |
1XXXX | 输入线圈(离散量输入) | 位 | 只读 | 10001~1FFFF | DI |
3XXXX | 输入寄存器 | 字 | 只读 | 30001~3FFFF | AI |
4XXXX | 保持(输出)寄存器 | 字 | 读/写 | 40001~4FFFF | AO |
Modbus协议中寄存器地址从“1”开始,而实际存储中地址从“0”开始。举例要读取寄存器编号40005(4为块编号,5为modbus寄存器地址)的寄存器数据,则应把“00 04”放入报文的地址域。
4、要读取的寄存器个数
寄存器个数占两个字节,高字节在前,低字节在后,下行报文使用。
5、数据的字节数
数据的字节数占一个字节,上行报文用,不同于寄存器个数。
6、数据域
数据域占n个字节,高字节在前,低字节在后。
7、CRC校验
CRC校验占两个字节,低字节在前,高字节在后。
五、报文实例
1、功能码举例说明(以03H读取保存寄存器为例)
主站询问报文格式
地址 | 功能码 | 寄存器起始地址高位 | 寄存器起始地址低位 | 寄存器数高位 | 寄存器数低位 | CRC |
11 | 03 | 00 | 6B(107) | 00 | 03 | XXXX |
功能:读从站保持寄存器4XXXX值。
注意:报文中寄存器起始地址00000对应设备中40001地址,其他顺延。
本例:读11H号从站保持寄存器值,起始地址=006BH=107,对应地址40108,寄存器数=0003,末地址=40108+3-1=40110;
因此,本报文功能:读17号从站3个保持寄存器40108——40110的值。
2、读40005、40006两个寄存器,假设从机地址为“1”
下行报文:01 03 00 04 00 02 85 ca
从机地址 | 功能码 | 寄存器起始地址 | 读取寄存器个数 | CRC校验 |
01 | 03 | 00 04 | 00 03 | 85 ca |
上行报文:01 03 04 00 00 00 00 21 33
从机地址 | 功能码 | 返回字节个数 | 寄存器40005数据 | 寄存器40006数据 | CRC校验 |
01 | 03 | 04 | 00 00 | 00 00 | 21 33 |
3、向40005寄存器中写入0X12、0X34,假设从机地址为“1”
下行报文:01 06 00 04 00 01 12 34 4a b0
从机地址 | 功能码 | 寄存器起始地址 | 读取寄存器个数 | 要写入的数据 | CRC校验 |
01 | 03 | 00 04 | 00 01 | 12 34 | 85 ca |
上行报文:01 06 00 04 00 01 12 34 4a b0
从机地址 | 功能码 | 寄存器起始地址 | 读取寄存器个数 | 写入的数据 | CRC校验 |
01 | 03 | 00 04 | 00 01 | 12 34 | 85 ca |