Modbus TCP 是一种应用于以太网的通讯协议,基于Modbus RTU协议。Modbus协议是一种应用于串行数据通信的协议,广泛应用于工业控制系统。Modbus TCP 将传统的 Modbus RTU 消息封装在 TCP/IP 报文中,使其能够在现代的以太网环境中进行通信。本文将详细介绍 Modbus TCP 协议的报文格式、各部分具体含义,并给出 C 语言的示例。

Modbus TCP 报文格式

Modbus TCP 报文主要包含以下部分:

  1. 事务标识符(Transaction Identifier):2 字节
  2. 协议标识符(Protocol Identifier):2 字节
  3. 长度(Length):2 字节
  4. 单元标识符(Unit Identifier):1 字节
  5. 功能码(Function Code):1 字节
  6. 数据(Data):n 字节

1. 事务标识符

事务标识符用于标识请求/响应报文对。客户端发起请求时生成一个唯一的事务标识符,服务器响应时使用相同的事务标识符。这使得客户端能够区分并正确处理并发请求。

2. 协议标识符

协议标识符用于区分不同的上层协议。对于 Modbus TCP 来说,协议标识符固定为 0x0000。

3. 长度

长度字段表示从单元标识符开始的报文总字节数。包括单元标识符、功能码和数据字段。

4. 单元标识符

单元标识符用于标识设备中的特定单元。在 Modbus TCP 中,单元标识符对应于 Modbus RTU 中的设备地址。

5. 功能码

功能码用于指示报文的操作类型。如读取保持寄存器、写入单个寄存器等。常见的功能码有:

  • 0x03:读取保持寄存器
  • 0x06:写入单个寄存器
  • 0x10:写入多个寄存器

6. 数据

数据字段的内容取决于功能码。例如,对于读取保持寄存器操作,数据字段包含起始寄存器地址和要读取的寄存器数量。

C 语言示例

以下是一个使用 C 语言实现的 Modbus TCP 客户端示例,用于读取保持寄存器:

#include #include #include #include #include #include #define BUFFER_SIZE 1024int main() {int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (client_socket == -1) {perror("socket");exit(1);}struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");server_addr.sin_port = htons(502);if (connect(client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {perror("connect");exit(1);}// 构建 Modbus TCP 读取保持寄存器请求报文unsigned char request[12] = {0x00, 0x01, // 事务标识符0x00, 0x00, // 协议标识符0x00, 0x06, // 长度0x01, // 单元标识符0x03, // 功能码:读取保持寄存器0x00, 0x00, // 起始寄存器地址0x00, 0x01// 要读取的寄存器数量};// 发送请求报文if (write(client_socket, request, sizeof(request)) == -1) {perror("write");exit(1);}// 接收响应报文unsigned char response[BUFFER_SIZE];int response_length = read(client_socket, response, BUFFER_SIZE);if (response_length == -1) {perror("read");exit(1);}// 解析响应报文if (response[7] != 0x03) {printf("Error: Invalid function code in response.\n");exit(1);}if (response[8] != 0x02) {printf("Error: Invalid data length in response.\n");exit(1);}int register_value = (response[9] << 8) | response[10];printf("Register value: %d\n", register_value);close(client_socket);return 0;}

以上示例创建一个 TCP 客户端,连接到 IP 地址为 “192.168.1.100”、端口号为 502 的 Modbus TCP 服务器。然后构造一个读取保持寄存器的请求报文,并发送到服务器。接收并解析服务器的响应报文,最后输出寄存器值。

请注意,此示例仅用于演示目的,实际应用可能需要考虑更多的错误处理和功能。在实际项目中,可以使用现有的 Modbus TCP 库,例如 libmodbus,以便更方便且安全地处理 Modbus TCP 通信。

【最后一个bug】多平台都有更新和发布,大家可以一键三连,关注+星标,不错过精彩内容~