一、什么是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协议在串行链路上的报文格式如下所示:
帧结构 = 从机地址 + 功能吗 + 数据 + 校验
从站地址 | 功能码 | 数据 | 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 |
0x01:从机的地址 0x06:修改功能,修改从机寄存器的数据(写入) 0x00 0x01: 代表修改的起始寄存器地址.说明修改0x0000-0x0001的存储内容 0x00 0x17: 要修改的数据值为0017 0x98 0x04: 循环冗余校验 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协议的效率比较低。
从上面的图中,看出: 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
高速令牌传递网络
|