功能码这个概念,我们可以这么去理解,先回到我们的初衷,协议的目的是为了数据传输,也就是为了读取数据和写入数据,我们已经确定好4个存储区,存储不同的数据类型,那么接下来我们就要对这些存储区进行读写,那么可能会产生很多种不同的行为,比如读取输入线圈存储区、读取输出线圈存储区,这就是两种不同的行为,同样的,如果用读取输入线圈存储区、读取输出线圈存储区,会比较麻烦,那么我们干脆给每种形成指定一个代号,那么这种代号就是功能码。
我们再来探讨一下,究竟有多少种不同的行为呢?
读取和写入是2种行为,存储区有4个,但是我们知道输入线圈和输入寄存器是只读的,因此不能进行写入,除去这2种的话,应该会产生6种不同的行为,如下图所示:
行为序号 | 具体行为 |
1 | 读取输入线圈 |
2 | 读取输出线圈 |
3 | 读取输入寄存器 |
4 | 读取保持寄存器 |
5 | 写入输出线圈 |
6 | 写入保持寄存器 |
然而,Modbus规约将写入输出线圈和写入保持寄存器这2种行为,又进一步做了细分,包括写入单个和写入多个,因此原来的6种行为就变成了8种行为,同时给每种行为设置一个代号,就形成了下图所示的功能码列表:
功能码 | 功能说明 |
0x01 | 读取输出线圈 |
0x02 | 读取输入线圈 |
0x03 | 读取保持寄存器 |
0x04 | 读取输入寄存器 |
0x05 | 写入单个线圈 |
0x06 | 写入单个寄存器 |
0x0F | 写入多个线圈 |
0x10 | 写入多个寄存器 |
Modbus严格来说,是一个标准化的规约,而不是一个具体协议。我们常说的设备A和设备B之间通过Modbus协议来通信,这句话其实是不严谨的。
Modbus规约上有三种不同的协议,分别是ModbusRtu、ModbusAscii、ModbusTcp。
一般来说,ModbusRtu和ModbusAscii是运行在串口上的协议,ModbusTcp是运行是以太网上的协议,但是这并非juedui的,我们也可以将ModbusRtu、ModbusAscii运行在以太网或光纤上使用,同样的,在串口网络里,我们也可以使用ModbusTcp的协议,因为协议只是一种规范,并不限制通信介质。
前面我们说了Modbus有三种不同的协议,分别是ModbusRtu、ModbusAscii、ModbusTcp,那么这三种协议的报文格式也是不同的,下面分别对这三种协议的报文格式进行说明:
ModbusRtu的报文格式如下:
第一部分:从站地址,占1个字节
第二部分:功能码,占1个字节
第三部分:数据部分,占N个字节
第四部分:校验部分,CRC校验,占2个字节
2. ModbusAscii的报文格式如下:
第一部分:开始字符(:)
第二部分:从站地址,占2个字节
第三部分:功能码,占2个字节
第四部分:数据部分,占N个字节
第五部分:校验部分,LRC校验,占2个字节
第六部分:结束字符(CRLF)
3. ModbusTcp的报文格式如下:
第一部分:事务处理标识符,占2个字节
第二部分:协议标识符,占2个字节
第三部分:长度,占2个字节
第四部分:单元标识符,占1个字节
第五部分:功能码,占1个字节
第六部分:数据部分,占N个字节
Modbus学习成本很低,因为协议是公开免费的,我们可以直接获取到《Modbus中文协议文档》。
同时,也有很多调试软件可以进行仿真调试,因此我们可以在不购买任何硬件的情况下,就把Modbus协议学好。
【协议文档和调试软件】可以联系助教老师获取。
Modbus 学习必须要配合相关的调试软件,可以达到事半功倍的效果,Modbus
学习必备的三大神器分别是 ModbusPoll、ModbusSlave 及 VSPD,ModbusPoll 软件主要用于仿真Modbus主站或 Modbus 客户端,ModbusSlave 软件主要用于仿真 Modbus 从站或 Modbus 服务器,而VSPD 全称 Configure Virtual Serial PortDriver,是用来给电脑创建虚拟串口使用的。
即使我们想要结合硬件,支持Modbus协议的设备也有很多,各种品牌PLC、各种品牌的仪表、各种温湿度传感器、流量计等都可以很好地支持Modbus协议。