# flechazo 的小知乎,欢迎大家造访啦😘

书接上回 QT 使用定时器

# 使用 Qt 读取电脑串口数据

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

# 设置串口

/* 搜索可用的串口,并添加到串口组合框 */
void MainWindow::SearchSerialPorts()
{
    ui->comboBoxPort->clear();
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        if(ui->comboBoxPort->count()>0){
            for(int idx=0; idx<ui->comboBoxPort->count(); idx++){
                QString itemName = ui->comboBoxPort->itemText(idx);
                QString itemCode = ui->comboBoxPort->itemData(idx, Qt::UserRole).toString();
                /*  do other things */
                if(itemName!=info.portName()){
                   ui->comboBoxPort->addItem(info.portName());//+info.description());
                }
            }
        }else{
            ui->comboBoxPort->addItem(info.portName());//+info.description());
        }
    }
}

/* 实现软件参变量的初始化设定 */
void MainWindow::InitialSetting()
{
    /* 填充串口号组合框 */
    SearchSerialPorts();

    /* 填充串口波特率 */
    ui->comboBoxBaud->addItem("9600");
    ui->comboBoxBaud->addItem("14400");
    ui->comboBoxBaud->addItem("19200");
    ui->comboBoxBaud->addItem("57600");
    ui->comboBoxBaud->addItem("115200");
    ui->comboBoxBaud->setCurrentIndex(4);

    /* 填充串口数据位 */
    ui->comboBoxData->addItem("7位");
    ui->comboBoxData->addItem("8位");
    ui->comboBoxData->addItem("9位");
    ui->comboBoxData->setCurrentIndex(1);

    /* 填充串口校验位 */
    ui->comboBoxParity->addItem("无校验");
    ui->comboBoxParity->addItem("奇校验");
    ui->comboBoxParity->addItem("偶校验");

    /* 填充串口停止位 */
    ui->comboBoxStop->addItem("1位");
    ui->comboBoxStop->addItem("1.5位");
    ui->comboBoxStop->addItem("2位");

    /* 为变量赋初值 */
    receivedBytes=0;
    transmitBytes=0;
}

# 打开串口

/* 打开串口 */
void MainWindow::on_actionConnect_triggered()
{
    serialPort->setPortName(ui->comboBoxPort->currentText());
    if(serialPort->open(QIODevice::ReadWrite))
    {
        /* 打开串口成功 */
        /* 设置波特率 */
        serialPort->setBaudRate(ui->comboBoxBaud->currentText().toInt());
        /* 设置数据位数 */
        switch(ui->comboBoxData->currentIndex())
        {
            case 1:serialPort->setDataBits(QSerialPort::Data8);break;
            default: break;
        }
        /* 设置奇偶校验 */
        switch(ui->comboBoxParity->currentIndex())
        {
            case 0: serialPort->setParity(QSerialPort::NoParity);break;
            default: break;
        }
        /* 设置停止位 */
        switch(ui->comboBoxStop->currentIndex())
        {
            case 1: serialPort->setStopBits(QSerialPort::OneStop);break;
            case 2: serialPort->setStopBits(QSerialPort::TwoStop);break;
            default: break;
        }
        /* 设置流控制 */
        serialPort->setFlowControl(QSerialPort::NoFlowControl);
        /* 连接槽函数 */
        connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::ReadSerialData);
        /* 设置控件可否使用 */
        ui->actionConnect->setEnabled(false);
        ui->actionClose->setEnabled(true);
        ui->actionRefresh->setEnabled(false);
    }
    else
    {
        /* 打开失败提示 */
        QMessageBox::information(this,tr("错误"),tr("打开串口失败!"),QMessageBox::Ok);
    }
}

# 读取数据

/* 从串口接收数据 */
void MainWindow::ReadSerialData()
{
    /* 用于接收超时处理 */
    flechazoTime_ms = 0;
    receiveflag=true;
    /* 先把接收到的数据存到这里 */
    rxDatas+=serialPort->readAll();
}

# 超时处理

/* 使用定时器定时处理哦https://zhuanlan.zhihu.com/p/690750411 */
void MainWindow::recievedata()
{
    flechazoTime_ms++;
    /* 检查是否接收到数据 并有2ms的超时 */
    if((receiveflag)&&(flechazoTime_ms>=2))
    {
        receiveflag=false;
        if(ui->checkBoxRecieve->isChecked()) //十六进制显示
        {
             context = rxDatas.toHex();
             context = context.toUpper();

             QByteArray buffer,tmp, src;
             buffer = QByteArray::fromHex(context.toLatin1());
             for(int i=0;i<rxDatas.size();i++){
                cmdprotocolparsing.byte[i] = buffer[i];
             }
             vprotocolcmdparsing("",rxDatas.size());

             src = context.toLatin1();
             for (int i = 0; i < src.size(); i++ )
             {
                 tmp.append(src.at(i));
                 if (i % 2) tmp.append(0x20);
             }
             context = tmp;
        }
        else    //ASCII显示
        {
            context = QString::fromLocal8Bit(rxDatas);
        }

        QString timeStrLine="["+QDateTime::currentDateTime().toString("hh:mm:ss")+"][接收]:🐬 ";
        context = timeStrLine+context;//+"\n\r";

        QString content = "<span style=\" color:blue;\">"+context+"</span>";
        ui->textBrowser->append(content);

        receivedBytes=receivedBytes+rxDatas.size();
        ui->lcdNumberRecieve->display(receivedBytes);

        ui->statusbar->showMessage(tr("成功读取%1字节数据").arg(rxDatas.size()));
        rxDatas.clear();
    }
}

# 发送数据

void MainWindow::WriteSerialData(QString qstring_context)
{
    /* 处理成16进制 */
    QByteArray flechazoSend_buffer;
    QString flechazoSend_msg="";
    if ( qstring_context.indexOf(" ") > 0)
    {
        bool ok;
        char data;
        QStringList list;
        list = qstring_context.split(" ");
        for (int i = 0; i < list.count(); i++)
        {
            if (list.at(i) == " ")
                continue;
            if (list.at(i).isEmpty())
                continue;
            data = (char)list.at(i).toInt(&ok, 16);
            if (!ok)
            {
                QMessageBox::information(this, tr("提示消息"), tr("输入的数据格式有错误!"), QMessageBox::Ok);
                return;
            }
            flechazoSend_buffer.append(data);
        }
        flechazoSend_msg = qstring_context.toUpper();
    }
    else
    {
        QByteArray tmp, src,myqsarraydata;
        myqsarraydata=qstring_context.toLatin1();
        flechazoSend_buffer = QByteArray::fromHex(myqsarraydata);
        src = qstring_context.toLatin1();
        for (int i = 0; i < src.size(); i++ )
        {
            tmp.append(src.at(i));
            if (i % 2) tmp.append(0x20);
        }
        flechazoSend_msg = tmp;
    }

    /* 发送数据 */
    if (serialPort && serialPort->isOpen() && serialPort->isWritable())
    {
        qDebug()<<"**************************buf : "<<flechazoSend_buffer.toHex();
        QString timeStrLine="["+QDateTime::currentDateTime().toString("hh:mm:ss")+"][发送]:🚀 ";
        QString content = "<span style=\" color:red;\">"+timeStrLine +flechazoSend_msg+"\n\r</span>";
        ui->textBrowser->append(content);

        /* 向串口发送数据 */
        serialPort->write(flechazoSend_buffer);
        ui->statusbar->showMessage(tr("发送数据成功"));

        /* 界面控制 */
        ui->textBrowser->setTextColor(Qt::red);
        transmitBytes +=flechazoSend_buffer.size();
        ui->lcdNumberSend->display(transmitBytes);
    }
}

# 关闭串口

/* 关闭串口 */
void MainWindow::on_actionClose_triggered()
{
    serialPort->clear();
    serialPort->close();

    /* 设置控件可否使用 */
    ui->actionConnect->setEnabled(true);
    ui->actionClose->setEnabled(false);
    ui->actionRefresh->setEnabled(true);
}

完结撒花🍁

大家有问题欢迎向我提问哦!

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

flechazo 微信支付

微信支付

flechazo 支付宝

支付宝

flechazo 贝宝

贝宝