使用 libmodbus 库实现 Modbus RTU 通信
libmodbus 是一个开源的 Modbus 协议库,支持 Modbus RTU 和 Modbus TCP 通信。本文将介绍如何在 C++ 中使用 libmodbus 库实现 Modbus RTU 通信。
1. 安装 libmodbus 库
在 Linux 系统上,可以通过以下命令安装 libmodbus:
sudo apt-get install libmodbus-dev
在 Windows 系统上,可以从 libmodbus 官网 下载预编译的库或源码自行编译。
2. 基本步骤
使用 libmodbus 实现 Modbus RTU 通信的基本步骤如下:
- 创建 Modbus RTU 上下文。
- 配置串口参数(波特率、数据位、校验位等)。
- 连接 Modbus 设备。
- 发送 Modbus 请求并读取响应。
- 关闭连接并释放资源。
3. 示例代码
以下是一个完整的 C++ 示例代码,演示如何使用 libmodbus 实现 Modbus RTU 通信。
#include <iostream>
#include <modbus/modbus.h>
int main() {
// 1. 创建 Modbus RTU 上下文
modbus_t* ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
if (ctx == nullptr) {
std::cerr << "无法创建 Modbus RTU 上下文" << std::endl;
return -1;
}
// 2. 设置从机地址
int slave_id = 1;
if (modbus_set_slave(ctx, slave_id) == -1) {
std::cerr << "设置从机地址失败" << std::endl;
modbus_free(ctx);
return -1;
}
// 3. 连接 Modbus 设备
if (modbus_connect(ctx) == -1) {
std::cerr << "连接 Modbus 设备失败" << std::endl;
modbus_free(ctx);
return -1;
}
// 4. 读取保持寄存器
uint16_t tab_reg[10] = {0};
int num_registers = 5; // 读取 5 个寄存器
int rc = modbus_read_registers(ctx, 0, num_registers, tab_reg);
if (rc == -1) {
std::cerr << "读取寄存器失败: " << modbus_strerror(errno) << std::endl;
} else {
std::cout << "读取到的寄存器值:" << std::endl;
for (int i = 0; i < rc; i++) {
std::cout << "寄存器 " << i << ": " << tab_reg[i] << std::endl;
}
}
// 5. 关闭连接并释放资源
modbus_close(ctx);
modbus_free(ctx);
return 0;
}
4. 代码说明
-
创建上下文:
- 使用
modbus_new_rtu创建 Modbus RTU 上下文。 - 参数包括串口设备路径(如
/dev/ttyUSB0)、波特率(如9600)、校验位(如'N'表示无校验)、数据位(如8)和停止位(如1)。
- 使用
-
设置从机地址:
- 使用
modbus_set_slave设置 Modbus 从机地址。
- 使用
-
连接设备:
- 使用
modbus_connect连接 Modbus 设备。
- 使用
-
读取寄存器:
- 使用
modbus_read_registers读取保持寄存器的值。 - 参数包括起始寄存器地址、寄存器数量和存储结果的数组。
- 使用
-
关闭连接:
- 使用
modbus_close关闭连接,并使用modbus_free释放上下文资源。
- 使用
5. 编译和运行
在 Linux 系统上,可以使用以下命令编译代码:
g++ -o modbus_rtu_example modbus_rtu_example.cpp -lmodbus
运行程序:
./modbus_rtu_example
6. 注意事项
-
串口权限:
- 确保当前用户对串口设备(如
/dev/ttyUSB0)有读写权限。 - 可以使用
sudo chmod 666 /dev/ttyUSB0修改权限。
- 确保当前用户对串口设备(如
-
错误处理:
- 每次调用
libmodbus函数后,应检查返回值以确保操作成功。
- 每次调用
-
调试:
- 可以使用
modbus_set_debug(ctx, TRUE)启用调试模式,查看详细的通信日志。
- 可以使用
通过以上步骤,您可以在 C++ 中使用 libmodbus 库实现 Modbus RTU 通信。