Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气)于1979年为使用可编程逻辑控制器(PLC)通信而发表的。现在的Modbus协议已经成为工业领域通信协议的业界标准,并且是工业电子设备之间常用的connect方式。
Modbus协议能够成为工业领域应用最广泛的协议,它必须具备以下几个特点:
1、free:这个是最大的前提,任何产品都是一样,只有通过free才能obtained前期最大的使用量。
2、简单:Modbus协议帧format简单紧凑,用户容易理解,厂商容易集成。
3、接口:Modbus协议只是一种规约,属于应用层的协议,因此不仅可以应用在串口(485/232/422),也可以在以太网、光纤、蓝牙、无线上传输。
存储区Category
我一般介绍Modbus协议的时候,喜欢站在Modbus规约制定者的角度,结合一些事物来对比说明,这样对很多人来说,可能会更加容易理解。
假设没有Modbus协议,我们想要制定一个协议,我们首先要明确,协议的目的是为了data传输,因此,为了更好地存储不同的data type,我们会将布尔和非布尔的data分开存储,因此,就有了线圈和register的概念。
线圈和register,这个经常被很多人诟病,认为不应该这么翻译,感觉不容易理解。从电气角度来看,在电气控制回路中,一般都是靠接触器或中间继电器来实现控制,接触器或中继最终靠的是线圈的得电和失电来控制触点闭合和断开,因此用线圈表示布尔量;而register在计算机中,就是用来存储data的,因此非布尔的data放在register里。
这个可以跟PLC的存储区来进行对比,西门子的I/Q/M都是线圈,V/T/C/DB都是register,三菱的X/Y都是线圈,D/W/H都是register,欧姆龙的CIO是线圈,D/W/H是register。
以西门子为例,虽然I和Q都表示线圈,但是他们的分工是不同的,I表示输入,Q表示输出,输入意味着该存储区里的值必须由外部设备接入,是只读的,输出表示输出结果给外部设备,是可读可写的。
因此,Modbus的线圈和register应该也按照只读、读写来进一步细分,因此这就形成了Modbus的存储区,如下表所示:
存储区代号
然而,上面表格里的存储区名称是一个全称,开发和使用中使用全称会比较麻烦,因此需要给他们取个别名,就像西门子的I/Q/M一样,这些都是西门子给存储区取的一个代号,所以Modbus也要给这些存储区取一个代号,干脆直接用数字吧,于是,就有了下面的规定:
这个其实就跟我们的姓名和小名一样,姓名是正式场合使用,日常场合,我们一般可以使用小名。
存储区范围
无论是什么存储区,都会有一个范围的限制,就像西门子的M区可能最大到8192,三菱的X区最大到2048,Modbus的每个存储区也应该规定一个范围,不能无限制使用。
Modbus是这么规定的,每个存储区的最大范围是65536,这个范围是很大的。
我们再以三菱的X区为例,如果最大范围是2048,那么意味着我们只能访问X0-X2047这些address,我们这里说的X0、X2047,就是我们常说的PLCaddress,那么这个address是怎么组成的呢?它是由存储区编号加上一个address索引组成,我们把这样的PLCaddress,理解为绝对address,后面的address索引,理解为相对address。
所谓绝对address,就是我们仅仅通过一个address名称,就能知道是什么存储区的第几个data,而这个第几个,就是我们说的相对address,因此绝对address是唯一的,相对address,每个存储区都有。
那么对于Modbus来说,我们的绝对address和相对address是怎么样的呢?
我们仍然遵从公式:绝对address=区号+相对address。
但是也会有一些不一样的地方,以保持型register为例,第一个绝对address是400001,这个地方不是400000,这个是由Modbus规约决定的,其它存储区也是类似的。
因此,Modbus存储区范围如下图所示:

正如上文所说,65536这个范围是很大的,但在实际使用中,我们一般用不了这么多address,一般情况下,10000以内就已经足够我们使用了,因此,为了方便起见,我们有一种短的address模型,如下图所示:

function code
function code这个概念,我们可以这么去理解,先回到我们的初衷,协议的目的是为了data传输,也就是为了读取data和写入data,我们已经确定好4个存储区,存储不同的data type,那么接下来我们就要对这些存储区进行读写,那么可能会产生很多种不同的行为,比如读取输入线圈存储区、读取输出线圈存储区,这就是两种不同的行为,同样的,如果用读取输入线圈存储区、读取输出线圈存储区,会比较麻烦,那么我们干脆给每种形成指定一个代号,那么这种代号就是function code。
我们再来探讨一下,究竟有多少种不同的行为呢?
读取和写入是2种行为,存储区有4个,但是我们知道输入线圈和输入register是只读的,因此不能进行写入,除去这2种的话,应该会产生6种不同的行为,如下图所示:
然而,Modbus规约将写入输出线圈和写入保持register这2种行为,又进一步做了细分,包括写入单个和写入多个,因此原来的6种行为就变成了8种行为,同时给每种行为设置一个代号,就形成了下图所示的function code列表:
Modbus规约中的function code其实不止这8个,还有一些function code是用于诊断或Exception Code,但是一般很少使用,这8种function code是最主要的核心function code。
协议Category
Modbus严格来说,是一个标准化的规约,而不是一个具体协议。我们常说equipmentA和设备B之间通过Modbus协议来通信,这句话其实是不严谨的。
Modbus规约上有三种不同的协议,分别是ModbusRtu、ModbusAscii、ModbusTcp。
一般来说,ModbusRtu和ModbusAscii是运行在串口上的协议,ModbusTcp是运行是以太网上的协议,但是这并非绝对的,我们也可以将ModbusRtu、ModbusAscii运行在以太网或光纤上使用,同样的,在串口网络里,我们也可以使用ModbusTcp的协议,因为协议只是一种规范,并不限制通信介质。
messageformat
前面我们说了Modbus有三种不同的协议,分别是ModbusRtu、ModbusAscii、ModbusTcp,那么这三种协议的messageformat也是不同的,下面分别对这三种协议的messageformat进行说明:
ModbusRtu的messageformat如下:
第一部分:slave address,占1个byte
第二部分:function code,占1个byte
第三部分:data部分,占N个byte
第四部分:校验部分,CRC check,占2个byte
2. ModbusAscii的messageformat如下:
第一部分:开始字符(:)
第二部分:slave address,占2个byte
第三部分:function code,占2个byte
第四部分:data部分,占N个byte
第五部分:校验部分,LRC verification,占2个byte
第六部分:End字符(CR LF)
3. ModbusTcp的messageformat如下:
第一部分:事务处理标识符,占2个byte
第二部分:Protocol Identifier,占2个byte
第三部分:Length,占2个byte
第四部分:Unit identifier,占1个byte
第五部分:function code,占1个byte
第六部分:data部分,占N个byte
debug软件
Modbus学习成本很低,因为协议是公开free的,我们可以直接obtained《Modbus中文协议Document》。
同时,也有很多debug软件可以进行仿真debug,因此我们可以在不购买任何硬件的情况下,就把Modbus协议学好。
【协议Document和debug软件】可以联系助教老师获取。
Modbus 学习必须要配合Related的debug软件,可以达到事半功倍的效果,Modbus
学习必备的三大神器分别是 ModbusPoll、ModbusSlave 及 VSPD,ModbusPoll 软件主要用于仿真 Modbus主站或 Modbus 客户端,ModbusSlave 软件主要用于仿真 Modbus 从站或 Modbus 服务器,而 VSPD 全称 Configure Virtual Serial Port Driver,是用来给电脑创建虚拟串口使用的。
即使我们想要结合硬件,支持Modbus协议equipment也有很多,各种品牌PLC、各种品牌的仪表、各种温湿度传感器、流量计等都可以很好地支持Modbus协议。
发表回复