Qt 线程串口

文章目录

  • ui设置
  • 创建线程函数
  • 初始串口
  • run函数接收发送数据
    • 读取数据
    • 处理读取的数据
    • 写入数据
    • 写入启动的命令
  • 主线程

Qt 线程串口_第1张图片

ui设置

Qt 线程串口_第2张图片

创建线程函数

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

初始串口

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;
    }
}

run函数接收发送数据

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

读取数据

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

处理读取的数据

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;
}

写入数据

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

写入启动的命令

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);                // 写入数据到串口
    }
}

主线程

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

}

你可能感兴趣的:(qt,开发语言)