Modbus RTU与TCP通信示例
准备工作
-
安装 libmodbus 库
-
Linux (Debian/Ubuntu):
sudo apt-get install libmodbus-dev
-
Windows: 下载预编译库 libmodbus for Windows,并配置开发环境。
-
示例
1.Modbus RTU (串行通信)
#include <stdio.h> #include <modbus/modbus.h> int main() { modbus_t *ctx; int rc; uint16_t tab_reg[1]; // 存储读取的寄存器值 // 创建RTU上下文 ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1); if (ctx == NULL) { fprintf(stderr, "无法创建RTU上下文\n"); return -1; } // 设置从机地址 modbus_set_slave(ctx, 1); // 设置超时时间(毫秒) modbus_set_response_timeout(ctx, 1, 0); // 连接设备 if (modbus_connect(ctx) == -1) { fprintf(stderr, "连接失败: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } // 读取保持寄存器(地址0,读取1个寄存器) rc = modbus_read_registers(ctx, 0, 1, tab_reg); if (rc == -1) { fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); } else { printf("寄存器值: %d\n", tab_reg[0]); } // 写入单个寄存器(地址0,值0xFF) rc = modbus_write_register(ctx, 0, 0xFF); if (rc == -1) { fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); } // 关闭连接 modbus_close(ctx); modbus_free(ctx); return 0; }
2. Modbus TCP (以太网通信)
#include <stdio.h> #include <modbus/modbus.h> int main() { modbus_t *ctx; int rc; uint16_t tab_reg[2]; // 存储读取的寄存器值 // 创建TCP上下文 ctx = modbus_new_tcp("192.168.1.100", 502); if (ctx == NULL) { fprintf(stderr, "无法创建TCP上下文\n"); return -1; } // 设置从机地址(部分TCP设备需要) modbus_set_slave(ctx, 1); // 连接服务器 if (modbus_connect(ctx) == -1) { fprintf(stderr, "连接失败: %s\n", modbus_strerror(errno)); modbus_free(ctx); return -1; } // 读取输入寄存器(地址0,读取2个寄存器) rc = modbus_read_input_registers(ctx, 0, 2, tab_reg); if (rc == -1) { fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); } else { printf("寄存器值: [%d, %d]\n", tab_reg[0], tab_reg[1]); } // 写入多个寄存器(地址10,写入值255和128) uint16_t write_data[2] = {255, 128}; rc = modbus_write_registers(ctx, 10, 2, write_data); if (rc == -1) { fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); } // 关闭连接 modbus_close(ctx); modbus_free(ctx); return 0; }
编译与运行
-
Linux 编译命令
gcc modbus_rtu_example.c -o rtu_demo -lmodbus gcc modbus_tcp_example.c -o tcp_demo -lmodbus
-
运行前确保串口权限:
sudo chmod 666 /dev/ttyUSB0
-
-
Windows 编译 在 Visual Studio 中配置
libmodbus
的库路径和链接选项。
关键函数说明
功能 | 函数 |
---|---|
创建RTU上下文 | modbus_new_rtu() |
创建TCP上下文 | modbus_new_tcp() |
设置从机地址 | modbus_set_slave() |
读取保持寄存器 | modbus_read_registers() |
写入单个寄存器 | modbus_write_register() |
写入多个寄存器 | modbus_write_registers() |
关闭连接 | modbus_close() / modbus_free() |
注意事项
-
地址对齐 Modbus 寄存器地址分为四类:
-
线圈 (0x0000-0xFFFF):
modbus_read_bits()
/modbus_write_bit()
-
离散输入 (0x0000-0xFFFF):
modbus_read_input_bits()
-
输入寄存器 (0x0000-0xFFFF):
modbus_read_input_registers()
-
保持寄存器 (0x0000-0xFFFF):
modbus_read_registers()
-
-
错误处理 检查所有函数的返回值,使用
modbus_strerror(errno)
获取错误信息。 -
调试工具 推荐先用 QModMaster 或 Modbus Poll 验证设备通信参数。