|
|
@@ -65,26 +65,96 @@ 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::readRegisters() |
|
|
|
{ |
|
|
|
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) |
|
|
|
return; |
|
|
|
|
|
|
|
// 读取所有D寄存器 (保持寄存器) |
|
|
|
readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000); |
|
|
|
// 获取所有已注册的寄存器ID |
|
|
|
QStringList regIds = registerManager->getAllRegisteredRegisters(); |
|
|
|
QMap<QString, QSet<int>> regMap; // 按类型分组存储地址 |
|
|
|
|
|
|
|
// 分组寄存器地址 |
|
|
|
for (const QString &id : regIds) { |
|
|
|
if (id.startsWith("D") || id.startsWith("M")) { |
|
|
|
bool ok; |
|
|
|
int addr = id.mid(1).toInt(&ok); |
|
|
|
if (ok && addr >= 0 && addr <= 4000) { |
|
|
|
regMap[id.left(1)].insert(addr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 读取D寄存器 (保持寄存器) |
|
|
|
if (regMap.contains("D")) { |
|
|
|
readRegisterGroup(QModbusDataUnit::HoldingRegisters, regMap["D"].values()); |
|
|
|
} |
|
|
|
|
|
|
|
// 读取所有M寄存器 (线圈) |
|
|
|
readRegisterGroup(QModbusDataUnit::Coils, 0, 4000); |
|
|
|
// 读取M寄存器 (线圈) |
|
|
|
if (regMap.contains("M")) { |
|
|
|
readRegisterGroup(QModbusDataUnit::Coils, regMap["M"].values()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count) |
|
|
|
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses) |
|
|
|
{ |
|
|
|
const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制 |
|
|
|
if (addresses.isEmpty()) return; |
|
|
|
|
|
|
|
QList<int> sortedAddrs = addresses; |
|
|
|
std::sort(sortedAddrs.begin(), sortedAddrs.end()); |
|
|
|
|
|
|
|
// 合并连续地址范围 |
|
|
|
int start = sortedAddrs.first(); |
|
|
|
int end = start; |
|
|
|
|
|
|
|
for (int i = 1; i < sortedAddrs.size(); i++) { |
|
|
|
if (sortedAddrs[i] == end + 1) { |
|
|
|
end = sortedAddrs[i]; |
|
|
|
} else { |
|
|
|
readAddressRange(type, start, end - start + 1); |
|
|
|
start = sortedAddrs[i]; |
|
|
|
end = start; |
|
|
|
} |
|
|
|
} |
|
|
|
readAddressRange(type, start, end - start + 1); |
|
|
|
} |
|
|
|
|
|
|
|
for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) { |
|
|
|
int readCount = qMin(MAX_REG_PER_REQUEST, count - addr); |
|
|
|
void ModbusManager::readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count) |
|
|
|
{ |
|
|
|
const int MAX_REG_PER_REQUEST = 120; |
|
|
|
|
|
|
|
QModbusDataUnit unit(type, addr, readCount); |
|
|
|
for (int offset = 0; offset < count; offset += MAX_REG_PER_REQUEST) { |
|
|
|
int readCount = qMin(MAX_REG_PER_REQUEST, count - offset); |
|
|
|
QModbusDataUnit unit(type, startAddr + offset, readCount); |
|
|
|
|
|
|
|
if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { |
|
|
|
QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; |
|
|
|