From 654893a248e920a7f30e570a4fadc30369fbe01e Mon Sep 17 00:00:00 2001 From: lipengpeng Date: Mon, 28 Jul 2025 12:59:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=95=8C=E9=9D=A2=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modbus.pro.user | 2 +- mymodbus.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++---- widget.cpp | 5 +++-- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/modbus.pro.user b/modbus.pro.user index c27cca7..bce9a42 100644 --- a/modbus.pro.user +++ b/modbus.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/mymodbus.cpp b/mymodbus.cpp index f0b9789..07b1836 100644 --- a/mymodbus.cpp +++ b/mymodbus.cpp @@ -3,6 +3,10 @@ MyModbus::MyModbus() { + this->stationAddress_ = 1; + this->functionCode_ = 0x01; + this->startAdress_ = 256; + this->length_ = 1; } void MyModbus::Set(quint16 stationAddress, quint16 functionCode, quint16 startAdress, quint16 length) @@ -86,15 +90,37 @@ QByteArray MyModbus::SendCommand() QByteArray MyModbus::Receive(const QByteArray &revMessage) { receive_.clear(); - if (CrcCheck(revMessage)) + + // 最小Modbus响应长度检查 + if(revMessage.size() < 4) + { // 地址1 + 功能码1 + CRC2 + return receive_; + } + + // 检查站地址匹配 + if(static_cast(revMessage[0]) != stationAddress_) + { + return receive_; + } + + // CRC校验 + if (!CrcCheck(revMessage)) { - this->receive_ = revMessage; + return receive_; } + + this->receive_ = revMessage; return receive_; } int MyModbus::ErrorCheck() { + // 异常响应最小长度检查 + if(receive_.size() < 5) + { + // 地址1 + 异常功能码1 + 异常码1 + CRC2 + return -1; // 特殊错误码表示协议错误 + } if ((receive_.at(1) & 0x80) == 0x80) { // MODBUS异常响应结构:地址 | 功能码+0x80 | 异常码 | CRC @@ -109,8 +135,14 @@ int MyModbus::ErrorCheck() QVector MyModbus::AnalReadCoil() { - quint8 byteCount = static_cast(receive_[2]); QVector coil; + if(receive_.size() < 6) + { + // 最小长度: 地址1 + 功能码1 + 长度1 + 数据1 + CRC2 + return coil; + } + + quint8 byteCount = static_cast(receive_[2]); for (int byteIndex = 0; byteIndex < byteCount; byteIndex++) { @@ -132,10 +164,16 @@ QVector MyModbus::AnalReadCoil() QVector MyModbus::AnalReadReg() { + QVector registers; + if(receive_.size() < 7) + { + // 最小长度: 地址1 + 功能码1 + 长度1 + 数据2 + CRC2 + return registers; + } + int byteCount = receive_.at(2); QByteArray data = receive_.mid(3, byteCount); - QVector registers; for (int i = 0; i < data.size(); i += 2) { quint16 value = (static_cast(data[i]) << 8) | static_cast(data[i+1]); diff --git a/widget.cpp b/widget.cpp index 8d22882..659e758 100644 --- a/widget.cpp +++ b/widget.cpp @@ -23,7 +23,7 @@ Widget::Widget(QWidget *parent) : connect(serialPort, &QSerialPort::readyRead, this, &Widget::onReadyRead); connect(recvTimer, &QTimer::timeout, this, &Widget::on_SerialData_ReadyToRead); - QObject::connect(&timer, &QTimer::timeout, [&]{ + QObject::connect(&timer, &QTimer::timeout, [this]{ if (comCount < 3) { ui->textEdit_2->append("通信超时,重新发送中"); @@ -116,11 +116,12 @@ void Widget::on_pushWrite_clicked() switch (ui->comboBox_gongnengma->currentIndex()) { case 2: //写多个线圈 + { QString sendData = ui->lineEdit->text().trimmed(); if (sendData.isEmpty()) { - QMessageBox::warning(this, "提示", "请至少输入一个数据,缺少的数据默认为0"); + QMessageBox::warning(this, "提示", "请至少输入一个数据"); return; } for (QChar ch : sendData) {