qt 上位机 modbus通讯


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtSerialPort/QtSerialPort>
#include <QSerialPortInfo>
#include "QDebug"
#include "QMessageBox"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QStringList ac;
     ser = new QSerialPort(this);
     foreach (const QSerialPortInfo &inf0, QSerialPortInfo::availablePorts()) {
            ac<<inf0.portName();
        }
        ui->comboBox->addItems(ac);
   qDebug()<<ac;



}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    ser->setPortName(ui->comboBox->currentText());
        ser->setBaudRate(ui->comboBox_2->currentText().toInt());
        ser->setDataBits(QSerialPort::Data8);
        ser->setStopBits(QSerialPort::OneStop);
        ser->setParity(QSerialPort::NoParity);
        ser->setFlowControl(QSerialPort::NoFlowControl);

        /* 打开串口提示框 */
        if (true == ser->open(QIODevice::ReadWrite))
        {
            QMessageBox::information(this, "提示", "串口打开成功");
            qDebug()<<"通讯成功";
             connect(ser,SIGNAL(readyRead()),this,SLOT(serialPortReadyRead()));
             ui->textEdit_3->setText("串口已打开");

        }
        else
        {
            QMessageBox::critical(this, "提示", "串口打开失败");
        }
        connect(ui->SEND,&QPushButton::click,[=](){
            QString str = ui->textEdit_2->toPlainText();
            QByteArray arr =  QString2Hex(str);
            ser->write(arr,arr.size());
        });

}

//字符串转Hex(QByteArray)类型
QByteArray MainWindow::QString2Hex(QString hexStr)
{
    QByteArray senddata;
    int hexdata, lowhexdata;
    int hexdatalen = 0;
    int len = hexStr.length();
    senddata.resize(len/2);
    char lstr, hstr;
    for(int i = 0; i < len; )
    {
        //将第一个不为' '的字符赋给hstr;
        hstr = hexStr[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        //当i >= len时,跳出循环
        if(i >= len)
            break;
        //当i < len时,将下一个字符赋值给lstr;
        lstr = hexStr[i].toLatin1();
        //将hstr和lstr转换为0-15的对应数值
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        //
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata * 16 + lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}
void MainWindow::on_pushButton_2_clicked()
{
    ser->close();
    qDebug()<<"关闭";
    ui->textEdit_3->setText("串口关闭");
}
//将单个字符串转换为hex
//0-F -> 0-15
char MainWindow::ConvertHexChar(char c)
{
    if((c >= '0') && (c <= '9'))
        return c - 0x30;
    else if((c >= 'A') && (c <= 'F'))
        return c - 'A' + 10;//'A' = 65;
    else if((c >= 'a') && (c <= 'f'))
        return c - 'a' + 10;
    else
        return -1;
}

void MainWindow::serialPortReadyRead()
{

    QByteArray temp = ser->readAll();
    QString str;
    str =  QString::fromLocal8Bit(temp);
    ui->textEdit->append(str);

}

我想用QT做一个上位机 这是一个小程序 大家帮我看看 我这个qt运行之后 发送报文一直没收到回应

你先用别的串口软件来发送,确认通信是否正常

建议先用调试工具看看 是否连接到串口, 并且监听串口的数据格式 是否符合modbus的格式规范

现在运行没收到回应,大概率是发送和接受的字节错误。需要仔细核对发送报文是否正确。

根据代码,分析出下面的可能:
1、在 MainWindow::QString2Hex 函数中,你在循环中使用了 continue 语句,但它没有跳过当前的循环迭代,而是直接进入了下一次迭代。
因此,这个函数可能无法正确地将输入的十六进制字符串转换为字节数组。
2、在 MainWindow::serialPortReadyRead 函数中,你使用了 QString::fromLocal8Bit(temp) 来将字节数组转换为字符串,但 temp 可能包含一些二进制数据,这可能会导致转换失败。你应该使用 QByteArray::toHex() 来将字节数组转换为十六进制字符串。
3、在 MainWindow::on_pushButton_clicked 函数中,你连接到 ui->SEND 按钮的点击事件,但是 lambda 函数中缺少了 ser 变量的引用。你应该使用 this->ser 来访问 ser 变量。
4、在 MainWindow::on_pushButton_2_clicked 函数中,你关闭了串口,但是并没有更新 ui->textEdit_3 的文本。你应该使用 ui->textEdit_3->setText("串口已关闭") 来更新文本。