Modbus通讯是整个工业领域比较通用的协议, 所以这里采用Modbus协议作为底层的通讯协议
Modbus协议的主要类型分三种
- Modbus RTU:二进制格式,适用于串行链路(如RS-232、RS-485),效率高。
- Modbus ASCII:ASCII格式,更易调试,但效率较低。
- Modbus TCP/IP:基于以太网的版本,支持现代网络,端口502。
这里主要针对Modbus RTU, Modbus TCP大同小异
存储区
按照读写分类可以分为只读和读写, Modbus协议里把只读称作输入, 读写称作输出; 按照数据类型分类, 可分为布尔类型和字类型, Modbus协议中把布尔类型称作线圈, 字类型称作寄存器, 所以排列组合后, Modbus协议有四个存储区
- 只读布尔, 称作输入线圈, Discrete Inputs
- 只读字, 称作输入寄存器, Input Registers
- 读写字, 称作保持寄存器, Holding Registers
总结成表格如下
存储区地址及功能码
Modbus协议针对不同的存储区预先定义好了一系列的地址区, 针对读写线圈或者寄存器定义了功能码, 其中写入功能码分别定义了单个写入功能码05, 06和批量写入功能码15, 16, 总结成表格如下
| | | | | | | |
|---|
| | | | | 00001 ~ 09999 或 000001 ~ 065535 | | |
| | | | | 10001 ~ 19999 或 100001 ~ 165535 | | |
| | | | | 30001 ~ 39999 或 300001 ~ 365535 | | |
| | | | | 40001 ~ 49999 或 400001 ~ 465535 | | |
报文
Modbus协议针对8个功能码, 对应了8条指令, 分别是
| | | | | |
|---|
| | | | | |
| | | | | |
| | | 读多个保持寄存器(Holding Registers) | | |
| | | 读多个输入寄存器(Input Registers) | | |
| | | | | |
| | | 写单个保持寄存器(Holding Register) | | |
| | | | | |
| | | 写多个保持寄存器(Holding Registers) | | |
Modbus协议的报文(Message)采用请求-响应机制,主设备(Master)发送请求报文,从设备(Slave)返回响应报文, 所以针对ModbusRTU会有主站从站之说, 报文基本结构(以Modbus RTU为例):
其中数据区针对不同的功能码, 结构会有少许区别, 之后在协议开发过程中会针对每一个功能具体说明, 这里先举个例子:
比如针对功能码 01 (0x01):读多个线圈(Read Coils)
请求报文如下
响应报文如下
补充概念
Modbus中的寄存器的标准大小是一个Word, 一个Word是两个字节, 也就是16个位
Modbus寄存器 = 1 Word = 16 bits = 2 Bytes, 每个寄存器占2字节,高字节在前
当表示浮点数或者32位整数时, 常常会听到大端还是小端, 这是因为浮点数占两个寄存器, 也就是4个字节, 4个字节的排列组合就是所谓的大端排列还是小端排列, 也就是常常在Modbus模拟软件中见到的ABCD或者BADC, 不同的排列得出的浮点数或者整数的结果是不同的, 这点需要注意.
下一节内容: 串口通讯