环境:Qt5.15.2
测试工具
- Virtual Serial Port Driver:用于创建成对的虚拟串口,一个用于发送,一个用于接收。
- Modbus Slave:用于模拟从机
示例
前提:打开Virtual Serial Port Driver,创建一对虚拟串口。Qt中实现Modbus简单通信的程序作为主机,Modbus Slava用于模拟从机。
- CMAKE核心配置:
# 设置源文件编码为UTF-8
if(MSVC)
add_compile_options(/utf-8)
endif()
# 查找Qt5及其组件
find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets SerialPort SerialBus)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets SerialPort SerialBus)
target_link_libraries(test_modbus PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::SerialPort
Qt${QT_VERSION_MAJOR}::SerialBus)
- 需要使用Modbus通信的类中组合QModbusRtuSerialMaster类对象:
#include <QModbusRtuSerialMaster>
QModbusRtuSerialMaster modbusDevice;
- 配置串口参数,打开串口
// 设置modbus串口参数
modbusDevice.setConnectionParameter(QModbusDevice::SerialPortNameParameter, QStringLiteral("COM4")); //串口名:COM1
modbusDevice.setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud9600); //波特率:9600
modbusDevice.setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8); //数据位:8位
modbusDevice.setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop); //停止位:1位
modbusDevice.setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity); //校验位:无校验
modbusDevice.connectDevice()
- 接收数据:
//定义"读请求"对象
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, 0, 10); //0是所要读取的寄存器起始地址,10是所要读取的寄存器个数
//向位于地址1的从机服务器发送请求
auto *reply = modbusDevice.sendReadRequest(readUnit, 1);
if (reply) {
//读取完毕就执行onReadyRead
connect(reply, &QModbusReply::finished, this,&MainWindow::onReadyRead);
}
// onReadyRead槽函数中
auto reply=qobject_cast<QModbusReply *>(sender()); //接收信号,并将信号发送者强制转换成QModbusReply类的对象
// 读取成功
if (reply->error() == QModbusDevice::NoError) //从机回复无异常
{
// 从reply中获取数据单元
const QModbusDataUnit unit = reply->result();
// 将数据值转换为字符串
QString dataStr;
for (int i = 0; i < unit.valueCount(); ++i) {
dataStr += QString::number(unit.value(i)) + " ";
}
reply->deleteLater(); //稍后卸载reply
}
// 读取失败
else //从机回复异常
{
reply->deleteLater(); //稍后卸载reply
return;
}
- 发送数据:
// 检查modbusDevice的连接状态
if (modbusDevice.state() != QModbusDevice::ConnectedState) {
return;
}
// 创建QModbusDataUnit对象,用于写入寄存器
QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, 0x02, 1); // 写入寄存器起始地址0x02,写入寄存器数量1
// 设置要写入的数据值为0
writeUnit.setValue(0, 3); //参数1:寄存器索引的偏移量,参数2:写入的值
// 发送写入请求
modbusDevice.sendWriteRequest(writeUnit, 1); //写入请求,写入地址为1的从机
ui->plainTextEdit->insertPlainText("写入成功");
- 关闭串口:
modbusDevice.disconnectDevice();
浙公网安备 33010602011771号