#include "modbusmanager.h" #include #include ModbusManager::ModbusManager(RegisterManager* regManager, QObject *parent) : QObject(parent), registerManager(regManager) { modbusDevice = new QModbusRtuSerialMaster(this); pollTimer = new QTimer(this); connect(modbusDevice, &QModbusClient::errorOccurred, this, [this](QModbusDevice::Error) { emit errorOccurred(modbusDevice->errorString()); }); connect(pollTimer, &QTimer::timeout, this, &ModbusManager::readRegisters); } ModbusManager::~ModbusManager() { stopSimulation(); disconnectDevice(); } bool ModbusManager::connectToDevice(const QString& portName, QSerialPort::BaudRate baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits) { if (modbusDevice->state() != QModbusDevice::UnconnectedState) { disconnectDevice(); } modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, portName); modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); if (!modbusDevice->connectDevice()) { emit errorOccurred(tr("连接失败: %1").arg(modbusDevice->errorString())); return false; } emit connectionStatusChanged(true); return true; } void ModbusManager::disconnectDevice() { if (modbusDevice->state() != QModbusDevice::UnconnectedState) { modbusDevice->disconnectDevice(); emit connectionStatusChanged(false); } } void ModbusManager::startSimulation(int interval) { pollTimer->start(interval); } void ModbusManager::stopSimulation() { pollTimer->stop(); } void ModbusManager::readRegisters() { if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) return; // 读取所有D寄存器 (保持寄存器) readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000); // 读取所有M寄存器 (线圈) readRegisterGroup(QModbusDataUnit::Coils, 0, 4000); } void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count) { const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制 for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) { int readCount = qMin(MAX_REG_PER_REQUEST, count - addr); QModbusDataUnit unit(type, addr, readCount); if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; pendingRequests[reply] = regType; connect(reply, &QModbusReply::finished, this, &ModbusManager::processModbusReply); } } } void ModbusManager::processModbusReply() { auto *reply = qobject_cast(sender()); if (!reply) return; if (reply->error() == QModbusDevice::NoError) { const QModbusDataUnit unit = reply->result(); QString regType = pendingRequests.value(reply); int startAddr = unit.startAddress(); for (uint i = 0; i < unit.valueCount(); i++) { int regAddr = startAddr + i; quint16 value = unit.value(i); QString regId = QString("%1%2").arg(regType).arg(regAddr); // 更新图元状态 registerManager->updateRegisterValue(regId, value); } } else { emit errorOccurred(tr("Modbus错误: %1").arg(reply->errorString())); } pendingRequests.remove(reply); reply->deleteLater(); } void ModbusManager::writeRegister(const QString& registerId, quint16 value) { if (registerId.isEmpty()) return; QModbusDataUnit::RegisterType regType = registerId.startsWith("D") ? QModbusDataUnit::HoldingRegisters : QModbusDataUnit::Coils; int regAddr = registerId.mid(1).toInt(); QModbusDataUnit writeUnit(regType, regAddr, 1); writeUnit.setValue(0, value); if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, slaveAddress)) { connect(reply, &QModbusReply::finished, this, [this, reply]() { if (reply->error() != QModbusDevice::NoError) { emit errorOccurred(tr("写入失败: %1").arg(reply->errorString())); } reply->deleteLater(); }); } }