| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809 |
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QVBoxLayout>
- #include <QHBoxLayout>
- #include <QSplitter>
- #include <QListView>
- #include <QTableView>
- #include <QHeaderView>
- #include <QDateTime>
- #include <QDebug>
- #include <QItemSelectionModel>
- #include <QtCharts/QDateTimeAxis>
- #include <QtCharts/QValueAxis>
- #include <QMessageBox>
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent),
- ui(new Ui::MainWindow),
- m_busCore(new SoftBusCore(this)),
- m_serialManager(new SerialManager(m_busCore, this)),
- m_dataTable(new QTableView(this)),
- m_serial_settingsModel(new QStandardItemModel(this)),
- m_deviceModel(new QStandardItemModel(this)),
- m_raw_dataModel(new QStandardItemModel(this)),
- m_bus_dataModel(new QStandardItemModel(this)),
- m_dataSeries(new QLineSeries())
- {
- ui->setupUi(this);
- // 初始化系统
- initializeSystem();
- // 创建UI
- createUI();
- // 创建连接
- createConnections();
- // 启动串口监控
- m_serialManager->startDiscovery();
- // 更新设备列表
- updateDeviceList();
- }
- MainWindow::~MainWindow()
- {
- // 停止串口监控
- m_serialManager->stopDiscovery();
- }
- void MainWindow::initializeSystem()
- {
- // 初始化数据库
- if (!m_busCore->initDB("raw_db", "bus_db"))
- {
- qCritical() << "Failed to initialize database";
- }
- // 注册串口设备
- foreach (const QString &portName, m_serialManager->getAvailablePorts())
- {
- DeviceInfo device;
- device.id = portName;
- device.type = "serial";
- device.address = 1;
- device.protocol = "modbus"; // 默认协议
- device.protocol_detail = "modbus-rtu";
- m_busCore->registerDevice(device);
- }
- }
- void MainWindow::createUI()
- {
- // 左侧设备列表
- ui->listV_device->setModel(m_deviceModel);
- ui->lineEdit_serial_send->setText("01 03 01 00 00 5C 44 0F ");
- // 右侧数据表格(上方为配置表格 ,下方为图表) )
- ui->tableV_serial_set->setModel(m_serial_settingsModel);
- ui->tableV_serial_set->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- m_serial_settingsModel->setHorizontalHeaderLabels({"参数", "值"});
- SerialManager::SerialConfig config = m_serialManager->getSerialConfig();
- QList<QStandardItem *> baudRateRow;
- baudRateRow << new QStandardItem("波特率") << new QStandardItem(QString::number(config.baudRate));
- m_serial_settingsModel->appendRow(baudRateRow);
- QList<QStandardItem *> dataBitsRow;
- dataBitsRow << new QStandardItem("数据位") << new QStandardItem(QString::number(config.dataBits));
- m_serial_settingsModel->appendRow(dataBitsRow);
- QList<QStandardItem *> parityRow;
- parityRow << new QStandardItem("校验") << new QStandardItem(QString::number(config.parity));
- m_serial_settingsModel->appendRow(parityRow);
- QList<QStandardItem *> stopBitsRow;
- stopBitsRow << new QStandardItem("停止位") << new QStandardItem(QString::number(config.stopBits));
- m_serial_settingsModel->appendRow(stopBitsRow);
- QList<QStandardItem *> flowControlRow;
- flowControlRow << new QStandardItem("流控") << new QStandardItem(QString::number(config.flowControl));
- m_serial_settingsModel->appendRow(flowControlRow);
- // Raw Data Table
- ui->tableV_raw_data->setModel(m_raw_dataModel);
- m_raw_dataModel->setHorizontalHeaderLabels({"时间", "来源", "协议", "数据"});
- ui->tableV_raw_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- ui->tableV_raw_data->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableV_raw_data->setSelectionBehavior(QAbstractItemView::SelectRows);
- ui->tableV_raw_data->setSelectionMode(QAbstractItemView::SingleSelection);
- // Bus Data Table
- ui->tableV_bus_data->setModel(m_bus_dataModel);
- m_bus_dataModel->setHorizontalHeaderLabels({"时间", "来源", "协议", "数据"});
- ui->tableV_bus_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- ui->tableV_bus_data->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableV_bus_data->setSelectionBehavior(QAbstractItemView::SelectRows);
- ui->tableV_bus_data->setSelectionMode(QAbstractItemView::SingleSelection);
- // ui->tableV_bus_data->setModel();
- }
- void MainWindow::createConnections()
- {
- // 设备注册/注销信号
- connect(m_busCore, &SoftBusCore::deviceRegistered, this, &MainWindow::updateDeviceList);
- connect(m_busCore, &SoftBusCore::deviceUnregistered, this, &MainWindow::updateDeviceList);
- // 总线消息存储信号
- connect(m_busCore, &SoftBusCore::busMessageStored, this, &MainWindow::updateChart);
- // 设备选择信号
- connect(ui->listV_device->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::onDeviceSelected);
- // 串口管理器信号
- connect(m_serialManager, &SerialManager::portDiscovered, this, [this](const QString &portName, const QString &desc)
- {
- Q_UNUSED(desc);
- updateDeviceList(); });
- connect(m_serialManager, &SerialManager::portRemoved, this, [this](const QString &portName)
- { updateDeviceList(); });
- connect(m_serialManager, &SerialManager::dataReceived, this, &MainWindow::onSerialDataReceived);
- }
- void MainWindow::updateDeviceList()
- {
- m_deviceModel->clear();
- // 添加串口设备
- foreach (const QString &portName, m_serialManager->getAvailablePorts())
- {
- QStandardItem *item = new QStandardItem("串口: " + portName);
- item->setData(portName, Qt::UserRole);
- m_deviceModel->appendRow(item);
- }
- // 添加其他类型设备(CAN、以太网等)
- // ...
- }
- void MainWindow::onDeviceSelected(const QModelIndex &index)
- {
- if (index.isValid())
- {
- // 显示设备相关数据
- QString deviceId = index.data(Qt::UserRole).toString();
- m_currentDeviceId = deviceId;
- m_serialManager->openSerialPort(QSerialPortInfo(deviceId));
- showRawData(deviceId);
- showBusMessages(deviceId);
- modbusSetting_ui(deviceId);
- }
- }
- void MainWindow::showRawData(const QString &deviceId)
- {
- m_raw_dataModel->removeRows(0, m_raw_dataModel->rowCount());
- // 查询最近10分钟的原始数据
- qint64 endTime = QDateTime::currentMSecsSinceEpoch();
- qint64 startTime = endTime - 10 * 60 * 1000;
- QList<QByteArray> rawData = m_busCore->queryRawData(deviceId, startTime, endTime);
- for (const QByteArray &data : rawData)
- {
- QList<QStandardItem *> row;
- // 时间戳是数据的前8个字节
- qint64 timestamp = *reinterpret_cast<const qint64 *>(data.constData());
- row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(timestamp).toString("hh:mm:ss"));
- row << new QStandardItem(deviceId);
- row << new QStandardItem("RAW");
- row << new QStandardItem(data.mid(8).toHex());
- m_raw_dataModel->appendRow(row);
- }
- }
- void MainWindow::showBusMessages(const QString &source)
- {
- // 查询最近10分钟的总线消息
- qint64 endTime = QDateTime::currentMSecsSinceEpoch();
- qint64 startTime = endTime - 10 * 60 * 1000;
- QList<BusMessage> messages = m_busCore->queryBusMessages(source, "data_processor", startTime, endTime);
- for (const BusMessage &msg : messages)
- {
- QList<QStandardItem *> row;
- row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(msg.timestamp).toString("hh:mm:ss"));
- row << new QStandardItem(msg.source);
- row << new QStandardItem(msg.payload["protocol"].toString());
- QString dataStr;
- if (msg.payload["protocol"] == "modbus")
- {
- dataStr = QString("ID:%1 FN:%2")
- .arg(msg.payload["slave_id"].toInt())
- .arg(msg.payload["function_code"].toInt());
- }
- else
- {
- dataStr = msg.payload["raw_data"].toString();
- }
- row << new QStandardItem(dataStr);
- m_bus_dataModel->appendRow(row);
- }
- }
- void MainWindow::updateChart(const BusMessage &message)
- {
- if (message.payload["protocol"] != "modbus")
- return;
- // 解析Modbus数据并更新图表
- QJsonArray dataArray = message.payload["data"].toArray();
- if (dataArray.size() > 0)
- {
- double value = dataArray[0].toDouble();
- qint64 timestamp = message.timestamp;
- m_dataSeries->append(timestamp, value);
- // 限制图表显示的数据点数量
- if (m_dataSeries->count() > 100)
- {
- m_dataSeries->removePoints(0, m_dataSeries->count() - 100);
- }
- }
- }
- // btn_fun
- // QCheckBox *checkBox_serial_hex;
- // QCheckBox *checkBox_serial_ascii;
- // QTextEdit *textEdit_serial;
- // QPushButton *btn_serial_clear;
- // QPushButton *btn_serial_send;
- void MainWindow::on_btn_serial_clear_clicked()
- {
- ui->textEdit_serial->clear();
- }
- void MainWindow::on_btn_serial_clear_send_clicked()
- {
- ui->lineEdit_serial_send->clear();
- }
- // 发送串口数据
- void MainWindow::on_btn_serial_send_clicked()
- {
- if (!m_serialManager->isPortOpen(m_currentDeviceId))
- {
- QMessageBox::warning(this, "串口未打开", "请先打开串口设备");
- return;
- }
- QString dataToSend = ui->lineEdit_serial_send->text();
- if (dataToSend.isEmpty())
- {
- QMessageBox::information(this, "发送数据", "请输入要发送的数据");
- return;
- }
- // 根据当前显示模式处理数据
- if (ui->checkbox_serial_hex->isChecked())
- {
- // 十六进制模式 - 将输入视为十六进制字符串
- QByteArray hexData = QByteArray::fromHex(dataToSend.toLatin1());
- m_serialManager->writeData(m_currentDeviceId, hexData);
- }
- else
- {
- // ASCII模式 - 直接发送文本
- m_serialManager->writeData(m_currentDeviceId, dataToSend.toUtf8());
- }
- // 在接收区显示发送的数据(带发送标记)
- QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
- ui->textEdit_serial->append(QString("<span style='color:blue;'>%1 [发送] %2</span>")
- .arg(timestamp)
- .arg(dataToSend));
- // 清空发送输入框
- // ui->lineEdit_serial_send->clear();
- }
- // 处理接收到的串口数据
- void MainWindow::onSerialDataReceived(const QString &portName, const QByteArray &data)
- {
- QString displayData;
- QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
- if (ui->checkbox_serial_hex->isChecked())
- {
- // 十六进制显示
- displayData = data.toHex(' ').toUpper();
- }
- else
- {
- // ASCII显示
- displayData = QString::fromUtf8(data);
- // 替换控制字符为可见表示
- displayData.replace('\r', "\\r");
- displayData.replace('\n', "\\n");
- displayData.replace('\t', "\\t");
- }
- ui->textEdit_serial->append(QString("<span style='color:green;'>%1 串口%2 [接收] %3</span>")
- .arg(timestamp)
- .arg(portName)
- .arg(displayData));
- }
- // 切换显示模式
- void MainWindow::on_checkbox_serial_hex_toggled(bool checked)
- {
- ui->checkbox_serial_ascii->setChecked(!checked);
- // 重新显示当前内容
- QString currentText = ui->textEdit_serial->toPlainText();
- ui->textEdit_serial->clear();
- ui->textEdit_serial->setText(currentText);
- }
- void MainWindow::on_checkbox_serial_ascii_toggled(bool checked)
- {
- ui->checkbox_serial_hex->setChecked(!checked);
- // 重新显示当前内容
- QString currentText = ui->textEdit_serial->toPlainText();
- ui->textEdit_serial->clear();
- ui->textEdit_serial->setText(currentText);
- }
- // 后续使用新的界面,这里是串口的modbus的相关设置
- void MainWindow::modbusSetting_ui(const QString &deviceId)
- {
- // 查询设备相关数据
- DeviceInfo device;
- device = m_busCore->getDeviceInfo(deviceId);
- if (device.id == "")
- return;
- // 设置协议类型
- if (device.protocol == "modbus")
- {
- if (device.protocol_detail == "modbus-rtu")
- {
- ui->checkbox_modbus_rtu->setChecked(true);
- ui->checkbox_modbus_ascii->setChecked(false);
- ui->checkbox_modbus_tcp->setChecked(false);
- }
- else if (device.protocol_detail == "modbus-ascii")
- {
- ui->checkbox_modbus_rtu->setChecked(false);
- ui->checkbox_modbus_ascii->setChecked(true);
- ui->checkbox_modbus_tcp->setChecked(false);
- }
- else if (device.protocol_detail == "modbus-tcp")
- {
- ui->checkbox_modbus_rtu->setChecked(false);
- ui->checkbox_modbus_ascii->setChecked(false);
- ui->checkbox_modbus_tcp->setChecked(true);
- }
- }
- else
- {
- ui->checkbox_modbus_rtu->setChecked(false);
- ui->checkbox_modbus_ascii->setChecked(false);
- ui->checkbox_modbus_tcp->setChecked(false);
- }
- // 其他设置
- ui->spinBox_modbus_slave_id->setValue(device.address);
- // 添加modbus指令
- ui->comboBox_modbus_control_list->clear();
- //
- QList<QByteArray> modbus_control_list = {
- "01 读线圈",
- "02 读离散输入",
- "03 读输入寄存器",
- "04 读保持寄存器",
- "05 写单个线圈",
- "06 写单个寄存器",
- "15 写多个线圈",
- "16 写多个寄存器"};
- for (const QByteArray &control : modbus_control_list)
- {
- ui->comboBox_modbus_control_list->addItem(control);
- }
- // 添加信号连接
- connect(ui->comboBox_modbus_control_list, QOverload<int>::of(&QComboBox::currentIndexChanged),
- this, &MainWindow::onModbusControlChanged);
- // 添加按钮连接
- connect(ui->btn_confirm_modbus_set, &QPushButton::clicked,
- this, &MainWindow::onConfirmModbusSet);
- connect(ui->btn_gen_modbus_datagram, &QPushButton::clicked,
- this, &MainWindow::onGenerateModbusDatagram);
- // 初始更新配置表格
- QString funcCode = device.properties["function_code"].toString();
- int index = ui->comboBox_modbus_control_list->findText(funcCode, Qt::MatchStartsWith);
- if (index != -1)
- {
- ui->comboBox_modbus_control_list->setCurrentIndex(index);
- }
- else
- {
- ui->comboBox_modbus_control_list->setCurrentIndex(0);
- }
- }
- void MainWindow::onModbusControlChanged(int index)
- {
- // 清除现有模型
- QStandardItemModel *model = new QStandardItemModel(this);
- ui->tableV_serial_modbus_set->setModel(model);
- ui->tableV_serial_modbus_set->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- model->setHorizontalHeaderLabels({"参数", "值"});
- // 获取当前选择的功能码
- QString selectedText = ui->comboBox_modbus_control_list->itemText(index);
- QString funcCode = selectedText.left(2);
- // 根据功能码设置不同的配置项
- if (funcCode == "01" || funcCode == "02")
- {
- // 读线圈/离散输入
- model->appendRow(createRow("起始地址", "0"));
- model->appendRow(createRow("线圈数量", "1"));
- }
- else if (funcCode == "03" || funcCode == "04")
- {
- // 读输入/保持寄存器
- model->appendRow(createRow("起始地址", "0"));
- model->appendRow(createRow("寄存器数量", "1"));
- }
- else if (funcCode == "05")
- {
- // 写单个线圈
- model->appendRow(createRow("线圈地址", "0"));
- model->appendRow(createRow("线圈状态", "0 (OFF)"));
- }
- else if (funcCode == "06")
- {
- // 写单个寄存器
- model->appendRow(createRow("寄存器地址", "0"));
- model->appendRow(createRow("寄存器值", "0"));
- }
- else if (funcCode == "15")
- {
- // 写多个线圈
- model->appendRow(createRow("起始地址", "0"));
- model->appendRow(createRow("线圈数量", "1"));
- model->appendRow(createRow("线圈状态", "0 (OFF)"));
- }
- else if (funcCode == "16")
- {
- // 写多个寄存器
- model->appendRow(createRow("起始地址", "0"));
- model->appendRow(createRow("寄存器数量", "1"));
- model->appendRow(createRow("寄存器值", "0"));
- }
- }
- void MainWindow::onConfirmModbusSet()
- {
- // 获取当前选中的设备
- QModelIndex index = ui->listV_device->currentIndex();
- if (!index.isValid())
- {
- return;
- }
- QString deviceId = index.data(Qt::UserRole).toString();
- // 获取设备信息
- DeviceInfo device = m_busCore->getDeviceInfo(deviceId);
- if (device.id.isEmpty())
- {
- return;
- }
- // 更新协议细节
- if (ui->checkbox_modbus_rtu->isChecked())
- {
- device.protocol_detail = "modbus-rtu";
- }
- else if (ui->checkbox_modbus_ascii->isChecked())
- {
- device.protocol_detail = "modbus-ascii";
- }
- else if (ui->checkbox_modbus_tcp->isChecked())
- {
- device.protocol_detail = "modbus-tcp";
- }
- // 更新从站地址
- device.address = ui->spinBox_modbus_slave_id->value();
- // 更新Modbus配置
- QJsonObject properties;
- properties["slave_id"] = ui->spinBox_modbus_slave_id->value();
- properties["function_code"] = ui->comboBox_modbus_control_list->currentText().left(2);
- // 保存表格中的配置参数
- QStandardItemModel *model = qobject_cast<QStandardItemModel *>(ui->tableV_serial_modbus_set->model());
- if (model)
- {
- for (int row = 0; row < model->rowCount(); ++row)
- {
- if (model->item(row, 0)->text() == "起始地址")
- {
- properties["start_address"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "线圈数量")
- {
- properties["coils_count"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "寄存器数量")
- {
- properties["registers_count"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "线圈地址")
- {
- properties["coil_address"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "线圈状态")
- {
- properties["coil_state"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "寄存器地址")
- {
- properties["register_address"] = model->item(row, 1)->text();
- }
- else if (model->item(row, 0)->text() == "寄存器值")
- {
- properties["register_value"] = model->item(row, 1)->text();
- }
- else
- {
- // 忽略其他参数
- }
- }
- }
- device.properties = properties;
- // 更新设备信息
- m_busCore->updateDevice(device);
- QMessageBox::information(this, "配置保存", "Modbus配置已成功保存");
- }
- void MainWindow::onGenerateModbusDatagram()
- {
- // 获取当前选中的设备
- QModelIndex index = ui->listV_device->currentIndex();
- if (!index.isValid())
- {
- return;
- }
- QString deviceId = index.data(Qt::UserRole).toString();
- // 获取设备信息
- DeviceInfo device = m_busCore->getDeviceInfo(deviceId);
- if (device.id.isEmpty() || !device.properties.contains("function_code"))
- {
- QMessageBox::warning(this, "生成报文", "请先配置Modbus参数");
- return;
- }
- // 获取功能码
- QString funcCodeStr = device.properties["function_code"].toString();
- bool ok;
- int funcCode = funcCodeStr.toInt(&ok);
- if (!ok)
- {
- QMessageBox::warning(this, "生成报文", "无效的功能码");
- return;
- }
- // 生成Modbus报文
- QByteArray datagram;
- // 添加从站地址
- datagram.append(static_cast<char>(device.address));
- // 添加功能码
- datagram.append(static_cast<char>(funcCode));
- // 根据功能码添加数据
- switch (funcCode)
- {
- case 1: // 读线圈
- case 2: // 读离散输入
- case 3: // 读输入寄存器
- case 4:
- { // 读保持寄存器
- int startAddr = device.properties["start_address"].toString().toInt();
- int count = device.properties["registers_count"].toString().toInt();
- datagram.append(static_cast<char>((startAddr >> 8) & 0xFF));
- datagram.append(static_cast<char>(startAddr & 0xFF));
- datagram.append(static_cast<char>((count >> 8) & 0xFF));
- datagram.append(static_cast<char>(count & 0xFF));
- break;
- }
- case 5:
- { // 写单个线圈
- int coilAddr = device.properties["coil_address"].toString().toInt();
- int coilState = device.properties["coil_state"].toString().toInt();
- datagram.append(static_cast<char>((coilAddr >> 8) & 0xFF));
- datagram.append(static_cast<char>(coilAddr & 0xFF));
- datagram.append(static_cast<char>(coilState ? 0xFF : 0x00));
- datagram.append(static_cast<char>(0x00));
- break;
- }
- case 6:
- { // 写单个寄存器
- int regAddr = device.properties["register_address"].toString().toInt();
- int regValue = device.properties["register_value"].toString().toInt();
- datagram.append(static_cast<char>((regAddr >> 8) & 0xFF));
- datagram.append(static_cast<char>(regAddr & 0xFF));
- datagram.append(static_cast<char>((regValue >> 8) & 0xFF));
- datagram.append(static_cast<char>(regValue & 0xFF));
- break;
- }
- case 15:
- { // 写多个线圈
- int startAddr = device.properties["start_address"].toString().toInt();
- int count = device.properties["coils_count"].toString().toInt();
- QString coilStates = device.properties["coil_state"].toString();
- // 计算字节数
- int byteCount = (count + 7) / 8;
- datagram.append(static_cast<char>((startAddr >> 8) & 0xFF));
- datagram.append(static_cast<char>(startAddr & 0xFF));
- datagram.append(static_cast<char>((count >> 8) & 0xFF));
- datagram.append(static_cast<char>(count & 0xFF));
- datagram.append(static_cast<char>(byteCount));
- // 添加线圈状态数据
- // 这里简化处理,实际需要解析线圈状态字符串
- for (int i = 0; i < byteCount; ++i)
- {
- datagram.append(static_cast<char>(0x00)); // 默认所有线圈为OFF
- }
- break;
- }
- case 16:
- { // 写多个寄存器
- int startAddr = device.properties["start_address"].toString().toInt();
- int count = device.properties["registers_count"].toString().toInt();
- QString regValues = device.properties["register_value"].toString();
- // 计算字节数
- int byteCount = count * 2;
- datagram.append(static_cast<char>((startAddr >> 8) & 0xFF));
- datagram.append(static_cast<char>(startAddr & 0xFF));
- datagram.append(static_cast<char>((count >> 8) & 0xFF));
- datagram.append(static_cast<char>(count & 0xFF));
- datagram.append(static_cast<char>(byteCount));
- // 添加寄存器数据
- // 这里简化处理,实际需要解析寄存器值字符串
- for (int i = 0; i < count; ++i)
- {
- datagram.append(static_cast<char>(0x00)); // 高字节
- datagram.append(static_cast<char>(0x00)); // 低字节
- }
- break;
- }
- default:
- QMessageBox::warning(this, "生成报文", "不支持的功能码");
- return;
- }
- // 如果是RTU模式,添加CRC校验
- if (device.protocol_detail == "modbus-rtu")
- {
- quint16 crc = calculateCRC(datagram);
- datagram.append(static_cast<char>(crc & 0xFF));
- datagram.append(static_cast<char>((crc >> 8) & 0xFF));
- }
- // 显示生成的报文
- ui->lineEdit_serial_send->setText(datagram.toHex(' ').toUpper());
- QMessageBox::information(this, "生成报文", "Modbus报文已生成并填充到发送框");
- }
- // CRC计算函数
- quint16 MainWindow::calculateCRC(const QByteArray &data)
- {
- quint16 crc = 0xFFFF;
- for (int i = 0; i < data.size(); ++i)
- {
- crc ^= static_cast<quint8>(data[i]);
- for (int j = 0; j < 8; j++)
- {
- if (crc & 0x0001)
- {
- crc = (crc >> 1) ^ 0xA001;
- }
- else
- {
- crc = crc >> 1;
- }
- }
- }
- return crc;
- }
- QList<QStandardItem *> MainWindow::createRow(const QString ¶m, const QString &defaultValue)
- {
- QList<QStandardItem *> row;
- row << new QStandardItem(param);
- row << new QStandardItem(defaultValue);
- return row;
- }
- void MainWindow::on_checkbox_modbus_rtu_toggled(bool checked)
- {
- if (checked)
- {
- ui->checkbox_modbus_ascii->setChecked(!checked);
- ui->checkbox_modbus_tcp->setChecked(!checked);
- if (m_currentDeviceId != "")
- {
- DeviceInfo device = m_busCore->getDeviceInfo(m_currentDeviceId);
- device.protocol = "modbus";
- device.protocol_detail = "modbus-rtu";
- m_busCore->registerDevice(device);
- }
- }
- }
- void MainWindow::on_checkbox_modbus_ascii_toggled(bool checked)
- {
- if (checked)
- {
- ui->checkbox_modbus_rtu->setChecked(!checked);
- ui->checkbox_modbus_tcp->setChecked(!checked);
- if (m_currentDeviceId != "")
- {
- DeviceInfo device = m_busCore->getDeviceInfo(m_currentDeviceId);
- device.protocol = "modbus";
- device.protocol_detail = "modbus-ascii";
- m_busCore->registerDevice(device);
- }
- }
- }
- void MainWindow::on_checkbox_modbus_tcp_toggled(bool checked)
- {
- if (checked)
- {
- ui->checkbox_modbus_rtu->setChecked(!checked);
- ui->checkbox_modbus_ascii->setChecked(!checked);
- if (m_currentDeviceId != "")
- {
- DeviceInfo device = m_busCore->getDeviceInfo(m_currentDeviceId);
- device.protocol = "modbus";
- device.protocol_detail = "modbus-tcp";
- m_busCore->registerDevice(device);
- }
- }
- }
|