• Qt 线程串口



    在这里插入图片描述

    ui设置

    在这里插入图片描述

    创建线程函数

    #include 
    #include 
    #include 
    #include 
    
    class SerialPort : public QThread
    {
        Q_OBJECT
    public:
        SerialPort();
        ~SerialPort();
    
    public:
        void InitPort(QString PortName);
        void wirteData();//写入数据
        void ProcessReceivedData(QByteArray);//处理数据
        quint8  CalculateChecksum(const QByteArray& data);//计算校验和
    signals:
        void SendData(float m_fVol[10]);//发送数据
    
    protected:
        void run();
    
    public slots:
        void readData();
        void handleBytesWritten(quint64 bytes);
    
    public:
        QSerialPort* port;
        QStringList serialPortNameList;//串口列表
        float m_fVol[10];//电压
        QByteArray m_receivedBuffer[4096];
        QByteArray receivedData;//接收到的数据
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    初始串口

    void SerialPort::InitPort(QString PortName)
    {
        // 查询所有串口设备
    //    QList serialList = QSerialPortInfo::availablePorts();
    
    //    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    //    {
    //        serialPortNameList << info.portName();
    //        qDebug()<<"serialPortName: "<
    //    }
    
    
        //qDebug()<
        port->setPortName(PortName);
        port->setBaudRate(19200, QSerialPort::AllDirections);//波特率
        port->setDataBits(QSerialPort::Data8);             // 数据位为8位
        port->setFlowControl(QSerialPort::NoFlowControl);  // 无流控制
        port->setParity(QSerialPort::NoParity);            // 无校验位
        port->setStopBits(QSerialPort::OneStop);           // 一位停止位
    
        if (port->open(QIODevice::ReadWrite))
        {
            qDebug() << "Port have been opened";
            wirteData();
        }
        else
        {
            qDebug() << "open it failed";
    
            return;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    run函数接收发送数据

    void SerialPort::run()
    {
        connect(port, &QSerialPort::bytesWritten, this, &SerialPort::handleBytesWritten);//向串口写数据
        connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
        exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    读取数据

    void SerialPort::readData()
    {
        if (port->bytesAvailable() > 0)
            {
                qint64 nReadSize = 4096;
                if(port->isOpen())
                {
                    QByteArray receivedData = port->read(nReadSize);
    
                    //qDebug()<
                    if (receivedData.size() >= 26)
                    {
                        ProcessReceivedData(receivedData); // 处理接收到的数据
                    }
                }
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    处理读取的数据

    void SerialPort::ProcessReceivedData(QByteArray receivedData)
    {
        //qDebug()<
        //qDebug()<
    
        if(receivedData.size() >= 26)
        {
            if (receivedData.at(0) == 'U' && receivedData.at(receivedData.length() - 1) == '\xAA')
            {
                // 检验校验和
                //qDebug()<
                QByteArray dataContent = receivedData.mid(1, 23);
    
                quint8 receivedChecksum = static_cast<quint8>(receivedData.at(24)); // 获取接收到的校验和
                quint8 calculatedChecksum = CalculateChecksum(dataContent); // 计算校验和
    
                if(receivedChecksum ==calculatedChecksum )//数据正确
                {
                    quint16 wT;
                    for (int j = 0; j < 10; ++j)
                    {
                        wT = static_cast<quint8>(receivedData[j*2+2]);
                        wT <<= 8;
                        wT += static_cast<quint8>(receivedData[j*2+1]);
                        m_fVol[j] = wT * 5000.0f / 1024;
                        emit SendData(m_fVol);
                    }
    
                }
    
    
            }
            else
            {
                receivedData.remove(0, 1);
            }
    
        }
    
    }
    
    quint8 SerialPort::CalculateChecksum(const QByteArray &data)
    {
        quint8 checksum = 0;
    
        for (int i = 0; i < data.size(); ++i)
        {
            checksum += static_cast<quint8>(data.at(i));
        }
    
        return checksum;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    写入数据

    void SerialPort::handleBytesWritten(quint64 bytes)
    {
        if (bytes > 0)
        {
            // 数据写入成功
            //qDebug()<
            connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
        } else {
            // 数据写入失败
            wirteData();//再次写入
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    写入启动的命令

    void SerialPort::wirteData()
    {
        if (port->isOpen())
        {
            QByteArray data;
            data.append(char(0x55)); // 添加数据 0x55 到数组
            data.append(char(0x01)); // 添加数据 0x01 到数组
            data.append(char(0x01)); // 添加数据 0x01 到数组
            data.append(char(0x00)); // 添加数据 0x00 到数组
            data.append(char(0x00)); // 添加数据 0x00 到数组
            data.append(char(0x00)); // 添加数据 0x00 到数组
            data.append(char(0x02)); // 添加数据 0x02 到数组
            data.append(char(0xAA)); // 添加数据 0xAA 到数组
            //qDebug()<
            port->clear(QSerialPort::Output); // 清除输出缓冲区
            port->write(data);                // 写入数据到串口
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    主线程

    #include 
    #include "serialport.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private:
        Ui::Widget *ui;
    
    public slots:
        void ReadData(float m_fVol[10]);
    
    
    public:
        SerialPort* m_Port;
    
    private slots:
        void on_pushButton_clicked();
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        m_Port =new SerialPort();
        ui->comboBox->addItem("COM1");
        ui->comboBox->addItem("COM2");
        ui->comboBox->addItem("COM3");
        ui->comboBox->addItem("COM4");
        ui->comboBox->addItem("COM5");
        ui->comboBox->addItem("COM6");
        ui->comboBox->addItem("COM7");
        ui->comboBox->addItem("COM8");
    
    
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::ReadData(float m_fVol[10])
    {
    
        QTextCursor tc = ui->textBrowser->textCursor();
        tc.movePosition(QTextCursor::End);
        //qDebug()<
        for(int i=0;i<10;i++)
        {
             tc.insertText(QString::number(m_fVol[i])+"mv\n");
             tc.insertText("\n");
        }
    
        tc.insertText("----------\n");
    
    
        ui->textBrowser->moveCursor(QTextCursor::End);
    }
    
    
    
    
    void Widget::on_pushButton_clicked()
    {
        if(ui->pushButton->text() == "连接")
        {
            m_Port->InitPort(ui->comboBox->currentText());
            connect(m_Port,&SerialPort::SendData,this,&Widget::ReadData);
            m_Port->start();
            ui->pushButton->setText("断开连接");
        }
        else {
            m_Port->port->close();
            disconnect(m_Port, &SerialPort::SendData, this, &Widget::ReadData); // 断开连接
            ui->pushButton->setText("连接");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 相关阅读:
    分布式链路追踪技术
    猿创征文 |【SpringBoot2】快速上手SpringBoot
    第七章 数学 AcWing 1533. 1 的个数
    java版本企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发
    git初步使用
    ARM处理器中断处理机制
    meta理解及使用
    策略模式和模板模式
    【第六章】STM32 / GD32 - 软件I2C读取温度传感器LM75AD
    Python中容易忽略的四个小知识点
  • 原文地址:https://blog.csdn.net/weixin_45672157/article/details/134377907