Modbus通信协议是由Modicon公司开发的应用在PLC或其他工业控制器上的一种通用语言。通过此协议,各控制器之间可以实现串行通信,Modbus通信协议定义了一个控制器能识别使用的消息结构,描述了主控制器访问从站设备的过程,例如规定从站怎样做出应答响应,检查和报告传输错误等。Modbus协议的
通信方式为主从方式。主站首先向从站设备发送通信请求指令,从节点根据请求指令中的功能码向主站发回回答数据。网络中的每个从站设备都必须分配给一个唯一的地址,最多可达31个从站设备。通过多达24种总线命令实现主控制器与从站设备之间的信息交换。从站设备只执行发给自己的指令,对于其它从站地址开头的报文不作应答。这种一问一答的通信模式,大大提高了通信的正确率。因其具有操作简单、高效、通信可靠等优点,Modbus协议已成为一个国际通信标准,得到了国际上大多数工控产品生产厂家的支持。该通信协议已广泛应用于机械、水利、电力、环保等行业设备中。
Modbus TCP通信协议可供自动化设备的监控使用。常见的应用是开发基于该协议的网关,通过网关可以将PLC、I/O模块和其它总线连到以太网上。Modbus TCP是在不改变原有的Modbus协议基础上,只是将其作为应用层协议简单的移植到TCP/IP协议上。Modbus TCP协议每一个呼叫都要求一个应答。利用TCP/IP协议,通过网页的形式可以使用户界面更加友好。利用网络浏览器就可以查看企业网内部的设备运行情况。Schneider公司已经为Modbus注册了502端口,这样就可以将实时数据嵌入到网页中,通过在设备中嵌入Web服务器,就可以将Web浏览器作为设备的操作终端。但是Modbus协议本身存在一些缺陷,它不支持诸如基于对象的通信模型等一些正在被广泛采用的网络新技术,用户在使用的时候,不得不手工配置一些参数,比如信息数据类型、寄存器号等等。
B.1 Modbus TCP 协议数据格式
TCP/IP 协议和以太网的链路层校验机制已可保证数据包传递的正确性,因此Modbus TCP 报文中不再存在 CRC-16 或 LRC 校验域,但需要添加一个 Modbus应用帧头(MBAP)。它可对 Modbus 的参数及功能进行解释。每个 TCP/IP 报文仅可含有一个 Modbus 帧。
在 Modbus TCP ADU 中,MBAP 头部占 7 个字节(含 4 个子域),及交易标识符 TI(Transaction Identifier)、协议标识符 PI(Protocol Identifier),长度标识符L(Length)(占用 2 字节,指明 Protocol Identifier 和 Data 域的总长度)和单元标识符UI(Unit Identifier)组成。TI 占用 2 字节,用来标识 Modbus 帧的次序,PI 占用 2字节,用于确认应用层协议。UI 占 1 字节,用于标识 Modbus 设备单元。功能码
占 1 字节,可分为位操作和 16 位字操作两类。功能码指出要进行的操作,如功能码 15 代表写多个位寄存器,功能码 06 表示对独立的 16 位字寄存器进行写操作。数据域最多可达 248 字节,其具体格式与功能码相关。当客户机发送请求数据时,数据域给出要操作的寄存器的起始地址(2 字节)和个数(l 字节);当服务器发送应答数据时,数据域给出被操作的寄存器个数(1 字节)及各寄存器状态值。图 B.1 给出了 Modbus 与 Modbus TCP 数据帧格式比较。

图 B.1 Modbus 与 Modbus TCP/IP 帧格式
Modbus TCP 的 ADU 数据单元规范如表 B.1 所示。

表 B.1 Modbus TCP 的 ADU 数据单元规范
在通过 Modbus TCP 传送数据之前,需要在客户机和服务器之间建立一个TCP/IP 连接。服务器使用端口 502 作为 Modbus TCP 的连接端口。Modbus TCP连接的建立通常由 TCP/IP Socket 接口的软件协议自动实现,因此对应用完全透明。一旦客户端和服务器之间的 TCP/IP 连接建立,同样的连接可以根据要求的方向用来传输任意数量的用户数据。客户端和服务器还可以同时建立多个TCP/IP连接,最大的连接数量取决于 TCP/IP 接口的规范。
当某一设备发出请求,则其相应的设备要做出响应。响应的数据格式如表B.2 所示。

表 B.2 Modbus TCP 响应数据格式
B.2 Modbus 常用功能码
在 Modbus 消息帧的功能码中较常使用的是 01、02、03、04、06 和 16 功能码,使用它们即可实现对从机的数字量和模拟量的读写操作。下面以在 RTU 传输模式下通讯为例,对这些功能码进行详细介绍。

下面是 2 个 Modbus 命令的主从机收发的数据包格式,其余的命令可参照其格式。
(1)功能码:03H
代码功能:读保持寄存器
说明:读从机保持寄存器的二进制数据,不支持广播。
查询:查询信息规定了要读的寄存器起始地址及寄存器的数量,寄存器寻址起始地址为 0000,寄存器 1-16 所对应的地址分别为 0-15。
响应:响应信息中的寄存器数据为二进制数据,每个寄存器分别对应 2 个字节,第一个字节为高位值数据,第二个字节为低位数据。
(2)功能码:10H(十进制为 16)
代码功能:预置多个寄存器
说明:把数据按顺序预置到各(4x 类型)寄存器中,广播时该功能代码可把数据预置到全部从机中的相同类型的寄存器中。需要注意的是该功能代码可越过控制器的内存保护,在寄存器中的预置值一直保持有效,只能由控制器的下一个逻辑来处理寄存器的内容,控制逻辑中无该寄存器程序时,则寄存器中的值保持不变。
查询:信息中规定了要预置的寄存器类型,寄存器寻址的起始地址为 0。查询数据区中指定了寄存器的预置值,M84 和 484 型控制器使用 10 位二进制数据,2 个字节,剩余的高 6 位置 0。而其他类型的控制器使用一个 16 位二进制数据,每个寄存器 2 个字节。
响应:正常响应返回从机地址、功能代码、起始地址和预置寄存器数。