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("连接");
    }

}
相关推荐
mengzhi啊1 小时前
QTreeWidget的右键菜单,展开和折叠,或者其他操作
qt
不爱学习的小枫1 小时前
scala的集合
开发语言·scala
梦醒沉醉1 小时前
Scala的初步使用
开发语言·后端·scala
小白学大数据1 小时前
Fuel 爬虫:Scala 中的图片数据采集与分析
开发语言·爬虫·scala
十年编程老舅1 小时前
用Qt手搓AI助手,挑战24小时开发DeepSeek Assistant!
qt·计算机毕设·c++项目·qt项目·deepseek·计算机毕设项目
贩卖纯净水.1 小时前
《React 属性与状态江湖:从验证到表单受控的实战探险》
开发语言·前端·javascript·react.js
JouJz1 小时前
Java基础系列:深入解析反射机制与代理模式及避坑指南
java·开发语言·代理模式
march of Time2 小时前
go注册rpc接口
qt·rpc·golang
白羊不吃白菜2 小时前
PAT乙级(1101 B是A的多少倍)C语言解析
c语言·开发语言
一号言安2 小时前
牛客python蓝桥杯11-32(自用)
开发语言·python