Qt 线程串口

文章目录

ui设置

创建线程函数

cpp 复制代码
#include <QObject>
#include <QThread>
#include <QSerialPort>
#include <QSerialPortInfo>

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;//接收到的数据
};

初始串口

cpp 复制代码
void SerialPort::InitPort(QString PortName)
{
    // 查询所有串口设备
//    QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();

//    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
//    {
//        serialPortNameList << info.portName();
//        qDebug()<<"serialPortName: "<<info.portName();
//    }


    //qDebug()<<PortName;
    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;
    }
}

run函数接收发送数据

cpp 复制代码
void SerialPort::run()
{
    connect(port, &QSerialPort::bytesWritten, this, &SerialPort::handleBytesWritten);//向串口写数据
    connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
    exec();
}

读取数据

cpp 复制代码
void SerialPort::readData()
{
    if (port->bytesAvailable() > 0)
        {
            qint64 nReadSize = 4096;
            if(port->isOpen())
            {
                QByteArray receivedData = port->read(nReadSize);

                //qDebug()<<receivedData.size();
                if (receivedData.size() >= 26)
                {
                    ProcessReceivedData(receivedData); // 处理接收到的数据
                }
            }
        }
}

处理读取的数据

cpp 复制代码
void SerialPort::ProcessReceivedData(QByteArray receivedData)
{
    //qDebug()<<receivedData;
    //qDebug()<<receivedData.size();

    if(receivedData.size() >= 26)
    {
        if (receivedData.at(0) == 'U' && receivedData.at(receivedData.length() - 1) == '\xAA')
        {
            // 检验校验和
            //qDebug()<<receivedData;
            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;
}

写入数据

cpp 复制代码
void SerialPort::handleBytesWritten(quint64 bytes)
{
    if (bytes > 0)
    {
        // 数据写入成功
        //qDebug()<<bytes;
        connect(port, &QSerialPort::readyRead, this, &SerialPort::readData);//向串口读数据
    } else {
        // 数据写入失败
        wirteData();//再次写入
    }
}

写入启动的命令

cpp 复制代码
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()<<char(0x55);
        port->clear(QSerialPort::Output); // 清除输出缓冲区
        port->write(data);                // 写入数据到串口
    }
}

主线程

cpp 复制代码
#include <QWidget>
#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();
};
cpp 复制代码
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()<<m_fovl;
    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("连接");
    }

}
相关推荐
hopetomorrow2 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
小牛itbull12 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i20 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
闲暇部落23 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
GIS瞧葩菜32 分钟前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming198737 分钟前
STL关联式容器之set
开发语言·c++
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
GIS 数据栈1 小时前
每日一书 《基于ArcGIS的Python编程秘笈》
开发语言·python·arcgis
Mr.131 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++
陌小呆^O^1 小时前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp