Qt中使用Modbus协议
Qt提供了Qt Modbus模块,支持Modbus RTU和Modbus TCP协议,可用于与硬件设备通信。以下是具体实现步骤:
环境准备 确保Qt安装时勾选了Qt Serial Port和Qt Modbus模块。在项目配置文件(.pro)中添加:
qmake
QT += serialport modbus
创建Modbus客户端
cpp
#include <QModbusRtuSerialMaster>
#include <QModbusTcpClient>
// RTU串口模式
QModbusRtuSerialMaster *modbusDevice = new QModbusRtuSerialMaster;
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM1");
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud19200);
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
// TCP模式
QModbusTcpClient *modbusDevice = new QModbusTcpClient;
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "192.168.1.100");
连接设备
cpp
if (!modbusDevice->connectDevice()) {
qDebug() << "连接失败:" << modbusDevice->errorString();
}
数据读写操作 读取保持寄存器(功能码0x03):
cpp
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, 0, 10);
if (auto *reply = modbusDevice->sendReadRequest(readUnit, 1)) {
if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, [this, reply]() {
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
for (uint i = 0; i < unit.valueCount(); i++)
qDebug() << "地址" << unit.startAddress() + i << "值:" << unit.value(i);
}
reply->deleteLater();
});
else
delete reply;
}
写入单个寄存器(功能码0x06):
cpp
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 5, {123});
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 1)) {
connect(reply, &QModbusReply::finished, this, [this, reply]() {
if (reply->error() == QModbusDevice::NoError)
qDebug() << "写入成功";
reply->deleteLater();
});
}
错误处理
cpp
connect(modbusDevice, &QModbusClient::errorOccurred, [](QModbusDevice::Error error) {
qDebug() << "Modbus错误:" << error;
});
断开连接
cpp
modbusDevice->disconnectDevice();
注意事项
- Modbus RTU需要正确配置串口参数(波特率、数据位等)
- 从站地址需要与硬件设备设置一致
- 读写操作是异步的,需要通过信号槽处理结果
- 工业环境中建议添加超时重试机制
- 对于大量数据读取,需注意Modbus协议的单帧限制(通常最多125个寄存器)
调试建议
- 使用Modbus调试工具(如Modbus Poll)验证硬件通信
- 启用Qt Modbus模块的调试输出:
cpp
QLoggingCategory::setFilterLevel("qt.modbus*", QtDebugMsg);
- 检查硬件设备的Modbus地址映射表,确保访问正确的寄存器地址