modbus总线有三种协议:modbus rtu协议、modbus ascii协议和modbus tcp协议,modbus总线活跃在工业通信领域。modbus rtu和modbus ascii擅长串行通信,比如基于rs485或者rs232的通信,而modbus tcp则擅长基于以太网的通信。由于底层所使用的结构不同,modbus的应用数据单元(application data unit,adu)有所不同。你可能并去清楚什么是adu,昌晖仪表下面来详细介绍。
为了进行通信,modbus规定了一种很简单的数据结构,被称为“协议数据单元”(protocol data unit,pdu)。协议数据单元由功能码+数据构成,如下面这张图:
功能码的长度为1个字节,它表示要执行的功能。比如常见的:01读取线圈;02读取离散量输入值;03读取保持寄存器值;05写单个线圈等;数据部分的长度为0-252个字节,它表示要读的地址或者要写入的值,不同的功能码对应的数据有所不同。比如01功能码,其数据为4个字节,其中前两个字节表示要读取的线圈的地址,后两个字节表示要读取线圈的数量;而对于05功能码,其数据也是4个字节,前两个字节表示要写入线圈的地址,后面两字节表示要写入的值。
协议数据单元有三种类型:请求型协议数据单元(request pdu)、应答型协议数据单元(response pdu)、及异常应答型协议数据单元(exception response pdu),更多关于协议数据单元的内容,大家可以去modbus官网()下载通信规范好好阅读。
协议数据单元是modbus的通用数据结构,它与底层物理结构无关,modbus rtu、modbus ascii和modbus tcp都使用相同的协议数据单元。但是,modbus在通信的时候,总要依赖物理网络。因此要把协议数据单元映射到物理网络上,这就形成了应用数据单元(application data unit,adu)。由于底层网络的不同,modbus tcp跟modbus rtu和modbus ascii的应用数据单元是不同的,modbus rtu和modbus ascii的adu结构如下图所示:
而modbus tcp的adu结构如下:
可以看到,modbus tcp的应用数据单元是在协议数据单元的基础上,添加了一个叫做“mbap头(mbap header)”的结构。mbap是英文“modbus aplication”的缩写,即“应用数据单元”的意思。
mbap头结构由7个字节构成,如下表所示:
其中:
◆传输标识符:用于标识应用数据单元,即请求和应答之间的配对;客户端对该部分进行初始化,服务器端将其拷贝到自己的adu中;
◆协议标识符:系统间的协议标识,0=modbus;
◆长度:接下来要发送的数据长度,即:单元标识符+pdu的总长度,以字节为单位;
◆单元标识符:用于系统间的站寻址,比如在以太网+串行链路的网络中,远程站的地址;
这就是modbus tcp的adu结构,即:mbap头+pdu,是不是很简单呢?modbus tcp的数据传输采用的是一种被称为“客户端/服务器”的模式,这也是上面的表格中会出现客户端/服务器功能描述的原因。其实,很多网络通信都采用的这种方式,比如大名鼎鼎的西门子的s7通信协议。在串行链路中,这种方式也称为主-从通信。
说道这里,大家可能会有一个疑惑。因为modbus在网络通信中,通常需要写明ip地址和端口号,为什么modbus tcp的adu中没有相关的内容呢?
哈哈,其实这是因为modbus tcp是一个应用层的协议,而你说的ip地址和端口号属于传输层/网络层的协议。还没明白,好吧,看看这张图:
你看,在逻辑上modbus tcp是在tcp层上的。在发送数据的时候,modbus tcp的应用数据单元首先向下传送给传输层,加上tcp协议的报文;再传送给网络层,加上ip协议的报文;再向下传送给数据链路层及物理层;接收的过程正好相反,从物理层一层一层的去掉相应层的报文,最终到达应用层。所以在使用modbus tcp进行数据传输的时候,是要配合tcp/ip协议来使用的。通常如果你使用电脑编程,就要用到socket技术;如果是使用plc编程,通常厂家已经把底层通信封装成库指令了,你只要直接调用就好了。比如西门子s7-200 smart/1200/1500等plc都有现成的modbus-tcp指令库。偷偷告诉你一声,昌晖仪表后续会写基于plc和基于pc的modbus-tcp通信的文章。
还有一点要特别说明一下,modbus tcp使用的端口号是502,一定要给modbus tcp预留好,不能被别人占用哦。