日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Qt串口回路信號讀取多線程14串口測試方案

來源: 責編: 時間:2023-11-15 17:16:56 252觀看
導讀QSerialPort串口一、思路串口測試分為三種:回路測試對傳485模式,可以傳輸更遠的距離二、環境Qt 6.4.3Qt serial port模塊Qt Creator 11.0.1三、添加QSerialPort打開Qt mataintenanceTool登錄添加/移動組件,點擊下一步主

QSerialPort串口

一、思路

串口測試分為三種:jqv28資訊網——每日最新資訊28at.com

  • 回路測試
  • 對傳
  • 485模式,可以傳輸更遠的距離

二、環境

  • Qt 6.4.3
  • Qt serial port模塊
  • Qt Creator 11.0.1

三、添加QSerialPort

  • 打開Qt mataintenanceTool
  • 登錄
  • 添加/移動組件,點擊下一步

jqv28資訊網——每日最新資訊28at.com

  • 主要是選擇Qt Serial Bus, Qt Serial Port
  • 點擊下一步
  • 點擊更新即可

四、語句介紹

1.數據控制流

數據控制流 USART_HardwareFlowControl ,控制流,這里的流指數據流,在數據傳輸中,流控制室管理兩個節點之間數據傳輸速率過程,以防止出現接收端的數據緩存區已滿,而發送端依然繼續發送數據,所以導致數據丟失。jqv28資訊網——每日最新資訊28at.com

(1) 工作原理jqv28資訊網——每日最新資訊28at.com

當接受端的數據緩沖區已滿,無法處理數據來時,就發出不再接受的信號,發送端則停止發送,直到發送端收到可以繼續發送的信號再發送數據,常見的硬件控制流和軟件控制流jqv28資訊網——每日最新資訊28at.com

(2) 硬件控制流jqv28資訊網——每日最新資訊28at.com

jqv28資訊網——每日最新資訊28at.com

硬件控制流jqv28資訊網——每日最新資訊28at.com

RTS和CTS原本是用來詢問和回答是否可以傳輸數據。在上面的連接上,就是告訴對方自己子否可以進行通訊,此時RTS和DTR都可以用來對數據流進行控制。jqv28資訊網——每日最新資訊28at.com

A端DTR(數據設備就緒)發出信號,當B端準備好后,B端的DTR(數據設備就緒)向A端的DSR(通訊設備就緒發送信號),然后就可以通過RTS(請求發送)和DTR(允許發送)來控制通信。jqv28資訊網——每日最新資訊28at.com

硬件控制流并不是單純依賴硬件,它仍然需要軟件去處理識別,硬件控制流所做的只是給出信號電平。jqv28資訊網——每日最新資訊28at.com

(3) 軟件控制流jqv28資訊網——每日最新資訊28at.com

軟件流控制(Software flow control)是在計算機數據鏈路中的一種控制方法,特別適合于RS-232串口通信;它是采用特殊字符來船速帶內信令,特殊編碼字符稱作XOFF與XON(分別表示transmit off與transmit on)。因此也被稱作XON/XOFF流控制jqv28資訊網——每日最新資訊28at.com

使用ASCII字符集,XOFF一般為字節值19(十進制),XON為字節值17jqv28資訊網——每日最新資訊28at.com

(4) 工作方式jqv28資訊網——每日最新資訊28at.com

注意:是接收方把XON/XOFF信號發給發送方來控制發送方何時發送數據,這些信號是與發送數據的傳輸方向相反的。jqv28資訊網——每日最新資訊28at.com

接收方利用XON信號告訴發送方,我已經準備好接受更多的數據了,利用XOFF信號告訴發送方停止發送數據,直到接收方發送XON信號告訴發送方我再次準備好了。jqv28資訊網——每日最新資訊28at.com

(5) 設置控制流模式jqv28資訊網——每日最新資訊28at.com

setFlowControl 函數:jqv28資訊網——每日最新資訊28at.com

// setFlowControl對端口控制進行相關設置 無流量控制serial->setFlowControl(QSerialPort::NoFlowControl);
  • NoFlowControl:沒有控制
  • hardware flow control :硬件流控制 (RTS/CTS,DTR /DSR等)
  • Software flow control :軟件流控制 (XON/XOFF)

jqv28資訊網——每日最新資訊28at.com

設置控制流jqv28資訊網——每日最新資訊28at.com

2.設置端口

設置端口的名稱,此名字可以使用短名稱或者長系統地址。jqv28資訊網——每日最新資訊28at.com

void QSerialPort::setPortName(const QString &name)

3.波特率

輸出傳輸的速率,每秒傳輸的比特數。jqv28資訊網——每日最新資訊28at.com

enum QSerialPort::BaudRate    /// 可以選擇的內容為

Constantjqv28資訊網——每日最新資訊28at.com

Valuejqv28資訊網——每日最新資訊28at.com

Descriptionjqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud1200jqv28資訊網——每日最新資訊28at.com

1200jqv28資訊網——每日最新資訊28at.com

1200 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud2400jqv28資訊網——每日最新資訊28at.com

2400jqv28資訊網——每日最新資訊28at.com

2400 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud4800jqv28資訊網——每日最新資訊28at.com

4800jqv28資訊網——每日最新資訊28at.com

4800 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud9600jqv28資訊網——每日最新資訊28at.com

9600jqv28資訊網——每日最新資訊28at.com

9600 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud19200jqv28資訊網——每日最新資訊28at.com

19200jqv28資訊網——每日最新資訊28at.com

19200 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud38400jqv28資訊網——每日最新資訊28at.com

38400jqv28資訊網——每日最新資訊28at.com

38400 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud57600jqv28資訊網——每日最新資訊28at.com

57600jqv28資訊網——每日最新資訊28at.com

57600 baud.jqv28資訊網——每日最新資訊28at.com

QSerialPort::Baud115200jqv28資訊網——每日最新資訊28at.com

115200jqv28資訊網——每日最新資訊28at.com

115200 baud.jqv28資訊網——每日最新資訊28at.com

4.數據位

設置數據位并保存到幀中,如果設置成功,則返回true,否則返回false,并設置一個錯誤代碼,可以通過訪問QSerialPort::error屬性的值來獲取該代碼。jqv28資訊網——每日最新資訊28at.com

如果在打開端口之前設置了該設置,則實際的串行端口設置將在QSerialPort::open()方法中自動完成,然后端口打開成功。jqv28資訊網——每日最新資訊28at.com

bool setDataBits(DataBits dataBits);DataBits dataBits() const;

jqv28資訊網——每日最新資訊28at.com

數據位jqv28資訊網——每日最新資訊28at.com

5.奇偶校驗位

jqv28資訊網——每日最新資訊28at.com

奇偶校驗位jqv28資訊網——每日最新資訊28at.com

bool setParity(Parity parity);Parity parity() const;

6.設置停止位

jqv28資訊網——每日最新資訊28at.com

停止位jqv28資訊網——每日最新資訊28at.com

bool setStopBits(StopBits stopBits);StopBits stopBits() const;

7.發送方式

Hex 16進制,本質上就是將字節數數組轉化為16進制,然后用字符串的形式發送出去。jqv28資訊網——每日最新資訊28at.com

五、對于ui參數隨數字變化如何設置

int p = 1;foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){    PortStringList += info.portName();    ui->port->addItem(info.portName());    // 構造對象名    QString objectName = QString("comlist%1").arg(p);    // 查找對象    QLineEdit *comlist = this->findChild<QLineEdit *>(objectName);    if(comlist) {        comlist->setText(info.portName());    }    p++;}

六、字符串截取

QString snap = QString("COM");int com_num = com.remove(snap).toInt();

七、源代碼

linux與windows端通用多線程串口,可同時檢測14個串口。jqv28資訊網——每日最新資訊28at.com

1.Com_Test.pro

QT       += core guiQT       += serialportgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++17# You can make your code fail to compile if it uses deprecated APIs.# In order to do so, uncomment the following line.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += /    comthread.cpp /    main.cpp /    mainwindow.cppHEADERS += /    comthread.h /    mainwindow.hFORMS += /    mainwindow.ui# Default rules for deployment.qnx: target.path = /tmp/$${TARGET}/binelse: unix:!android: target.path = /opt/$${TARGET}/bin!isEmpty(target.path): INSTALLS += target

2.comthread.h

#ifndef COMTHREAD_H#define COMTHREAD_H#include <QObject>#include <QSerialPort>#include <QSerialPortInfo>#include <QDebug>#include <QThread>class ComThread :public QObject{    Q_OBJECTpublic:    explicit ComThread(QObject *parent = nullptr);    explicit ComThread(QString portname,qint32 rate,qint32 date,qint32 check_num,qint32 stop_num);    explicit ComThread(qint32 rate,qint32 date,qint32 check_num,qint32 stop_num);    explicit ComThread(QString portname);    // 拷貝構造函數    explicit ComThread(const ComThread &other);    ComThread& operator = (const ComThread &other)    {        qDebug()<<"進入拷貝";        if(this != &other)        {            qDebug()<<"進入拷貝賦值";            this->m_com = other.m_com;            this->mSerialPort = other.mSerialPort;            this->m_check_num = other.m_check_num;            this->m_date = other.m_date;            this->m_rate = other.m_rate;            this->m_stop_num = other.m_stop_num;            qDebug()<<"賦值結束";        }        qDebug()<<"返回值";        return *this;    }    ~ ComThread();public slots:    // 接受傳入的串口數據    void slot_recv_com(QString portname,qint32 rate,qint32 date,qint32 check_num,qint32 stop_num);    void slot_recv_com_s(qint32 rate,qint32 date,qint32 check_num,qint32 stop_num);    void slot_recv_com_name(QString portname);    // 對應主線程的信號,需要的槽函數    // 1,打開串口槽函數    // 2,關閉串口槽函數    void slot_openPort();    void slot_closePort();    void slot_handlMessage();    void serial_signal();private:    QSerialPort* mSerialPort;    QString m_com;    qint32 m_rate;    qint32 m_date;    qint32 m_check_num;    qint32 m_stop_num;    QByteArray  Receivetext;signals:    // 發送信號    // 發送字節    void already_send_byte(QString com ,qint32 num);    // 發送接受字節    void already_receive_byte(QString com ,qint32 num);    // 發送是否成功    void result(QString com ,qint32 num);  // 0代表失敗 1,代表成功    // 發送接受字符串    void already_receive_string(QString com ,QString string);    void send_com_signal(QString com,bool DTRstate,bool DCDstate,bool DSRstate,bool RINGRstate,bool RTSstate,bool CTSstate,bool STDstate,bool SRDstate);};#endif // COMTHREAD_H

3.comthread.cpp

#include "comthread.h"ComThread::ComThread(QObject *parent)    : QObject{parent}{    //    mSerialPort = nullptr;}ComThread::ComThread(QString portname){    m_com = portname;}ComThread::ComThread(const ComThread &other){//    qDebug()<<"進入賦值拷貝";    this->m_com = other.m_com;    this->mSerialPort = other.mSerialPort;    this->m_check_num = other.m_check_num;    this->m_date = other.m_date;    this->m_rate = other.m_rate;    this->m_stop_num = other.m_stop_num;}ComThread::ComThread(QString portname, qint32 rate,qint32 date,qint32 check_num,qint32 stop_num){    m_com = portname;    m_rate = rate;    m_date = date;    m_check_num = check_num;    m_check_num = stop_num;}ComThread::ComThread(qint32 rate, qint32 date, qint32 check_num, qint32 stop_num){    m_rate = rate;    m_date = date;    m_check_num = check_num;    m_check_num = stop_num;}ComThread::~ComThread(){    if(mSerialPort->isOpen())    {        mSerialPort->close();    }    delete mSerialPort;}void ComThread::slot_recv_com(QString portname, qint32 rate, qint32 date, qint32 check_num, qint32 stop_num){    m_com = portname;    m_rate = rate;    m_date = date;    m_check_num = check_num;    m_stop_num = stop_num;}void ComThread::slot_recv_com_s(qint32 rate, qint32 date, qint32 check_num, qint32 stop_num){    m_rate = rate;    m_date = date;    m_check_num = check_num;    m_stop_num = stop_num;}void ComThread::slot_recv_com_name(QString portname){    m_com = portname;}void ComThread::slot_openPort(){    mSerialPort = new QSerialPort();   //  qDebug()<<" "<< m_com<<" "<<m_rate<<" "<<m_date<<" "<<m_check_num<<" "<<m_stop_num;    // 設置串口對應的名稱和波特率    mSerialPort->setPortName(m_com);    mSerialPort->setBaudRate(m_rate);    switch(m_date)    {        //設置對應的數據位        case5:mSerialPort->setDataBits(QSerialPort::Data5);break;        case6:mSerialPort->setDataBits(QSerialPort::Data6);break;        case7:mSerialPort->setDataBits(QSerialPort::Data7);break;        case8:mSerialPort->setDataBits(QSerialPort::Data8);break;        // 若剛開始設置為空,端口打開之后再次進行相關的設置        // 若沒有選擇就不設置,端口打開之后仍可以設置        //default:serial->setDataBits(QSerialPort::UnknownDataBits);    }    switch(m_check_num)    {        case0:mSerialPort->setParity(QSerialPort::NoParity);break;        case1:mSerialPort->setParity(QSerialPort::EvenParity);break;        case2:mSerialPort->setParity(QSerialPort::OddParity);break;        case3:mSerialPort->setParity(QSerialPort::SpaceParity);break;        case4:mSerialPort->setParity(QSerialPort::MarkParity);break;            //default:serial->setParity(QSerialPort::UnknownParity);    }    switch(m_stop_num)    {        case0:mSerialPort->setStopBits(QSerialPort::OneStop);break;        case1:mSerialPort->setStopBits(QSerialPort::OneAndHalfStop);break;        case2:mSerialPort->setStopBits(QSerialPort::TwoStop);break;        //default:serial->setStopBits(QSerialPort::UnknownStopBits);    }    // 關聯讀取信號與槽函數,處理信息    mSerialPort->setFlowControl(QSerialPort::NoFlowControl);    connect(mSerialPort,&QSerialPort::readyRead,this,&ComThread::slot_handlMessage);    qDebug()<<"ComThread slot_openport ThreadID"<< QThread::currentThreadId();    if(mSerialPort->open(QIODevice::ReadWrite))    {        this->serial_signal();        // 發送數據        for(int i = 0;i<5;i++)        {            QString realbom = QString("RealReal");            QByteArray send = realbom.toUtf8();            // qDebug()<<send<<"Byte大小:"<<send.length();            mSerialPort->write(send);            emit already_send_byte(m_com,send.length());            // QThread::msleep(1000);            mSerialPort->waitForReadyRead(10); // 接受數據        }        // qDebug()<<"發送完畢";        // mSerialPort->waitForReadyRead(100); // 接受數據        this->slot_closePort();    }    else    {        //  qDebug()<<"return false";        // 關閉信號        emit result(m_com,0);    };    if(Receivetext.size() == 0)    {        //完全沒有接收到數據        emit result(m_com,0);    }}void ComThread::slot_closePort(){    if(mSerialPort->isOpen())    {        mSerialPort->close();    }}void ComThread::slot_handlMessage(){    qDebug()<<"調用了此信號";    // mSerialPort->waitForBytesWritten(100);    Receivetext = mSerialPort->readAll();    // qDebug()<<"接收:"<<QString::fromUtf8(Receivetext)<<"Byte大小:"<<Receivetext.length();    emit already_receive_byte(m_com,Receivetext.length());    emit already_receive_string(m_com,QString::fromUtf8(Receivetext));    if(Receivetext == QString("RealReal") && Receivetext.length() == 7)    {        emit result(m_com,1);    }    else    {        emit result(m_com,0);    }}void ComThread::serial_signal(){    // 獲取相關高低電壓值No    // bool NOstate = serial->pinoutSignals()& QSerialPort::NoSignal; // 沒有信號    // 數據終端準備好    bool DTRstate = mSerialPort->pinoutSignals()& QSerialPort::DataTerminalReadySignal;    // 載波信號    bool DCDstate = mSerialPort->pinoutSignals()& QSerialPort::DataCarrierDetectSignal;    // 數據準備好    bool DSRstate = mSerialPort->pinoutSignals()& QSerialPort::DataSetReadySignal;    //    bool RINGRstate = mSerialPort->pinoutSignals()& QSerialPort::RingIndicatorSignal;    // 請求發送    bool RTSstate = mSerialPort->pinoutSignals()& QSerialPort::RequestToSendSignal;    // 清除發送    bool CTSstate = mSerialPort->pinoutSignals()& QSerialPort::ClearToSendSignal;    // 發送數據    bool STDstate = mSerialPort->pinoutSignals()& QSerialPort::SecondaryTransmittedDataSignal;    // 接受數據    bool SRDstate = mSerialPort->pinoutSignals()& QSerialPort::SecondaryReceivedDataSignal;    emit send_com_signal(m_com,DTRstate,DCDstate,DSRstate,RINGRstate,RTSstate,CTSstate,STDstate,SRDstate);    /*    if(DTRstate)    {//        ui->DTR->setStyleSheet("background-color:red");        qDebug()<<"DTRstate";    }    if(DCDstate)    {//        ui->DCD->setStyleSheet("background-color:red");        qDebug()<<"DCDstate";    }    if(DSRstate)    {//        ui->DSR->setStyleSheet("background-color:red");        qDebug()<<"DSRstate";    }    if(RINGRstate)    {//        ui->PNG->setStyleSheet("background-color:red");        qDebug()<<"RINGRstate";    }    if(RTSstate)    {//        ui->RTS->setStyleSheet("background-color:red");         qDebug()<<"RTSstate";    }    if(CTSstate)    {//        ui->CTS->setStyleSheet("background-color:red");         qDebug()<<"CTSstate";    }    if(STDstate)    {//        ui->STD->setStyleSheet("background-color:red");         qDebug()<<"STDstate";    }    if(SRDstate)    {//        ui->SRD->setStyleSheet("background-color:red");         qDebug()<<"SRDstate";    }*/}

4.mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include "comthread.h"#include <QThread>//#include <QThreadPool>QT_BEGIN_NAMESPACEnamespace Ui { class MainWindow; }QT_END_NAMESPACEclass MainWindow :public QMainWindow{    Q_OBJECTpublic:    MainWindow(QWidget *parent = nullptr);    ~MainWindow();signals:    void sig_recv_com(QString portname, qint32 rate, qint32 date, qint32 check_num, qint32 stop_num);    void sig_recv_com_s(qint32 rate, qint32 date, qint32 check_num, qint32 stop_num);    void sig_recv_com_name(QString portname);    void sig_openPort();    void sig_closePort();public slots:    // 接受子線程傳回的數據    void slots_already_send_byte(QString com ,qint32 num);    // 接受字節    void slots_already_receive_byte(QString com ,qint32 num);    // 是否成功    void slots_result(QString com ,qint32 num);  // 0代表失敗 1,代表成功    // 接受字符串    void slots_already_receive_string(QString com ,QString string);    // 接受引腳信號    void send_com_signal(QString com,bool DTRstate,bool DCDstate,bool DSRstate,bool RINGRstate,bool RTSstate,bool CTSstate,bool STDstate,bool SRDstate);private slots:    void on_serial_test_clicked();protected:private:    Ui::MainWindow *ui;    QStringList PortStringList; // 串口列表//    QThreadPool *pool = QThreadPool::globalInstance();    ComThread *comthread;//    std::vector<ComThread> comthread;    QThread *mthread;    QString snap;};#endif // MAINWINDOW_H

5.mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent)    : QMainWindow(parent)    , ui(new Ui::MainWindow){    ui->setupUi(this);    //設計循環,將數據放入list列表當中    int p =1;    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())    {        PortStringList += info.portName();        ui->port->addItem(info.portName());        // 構造對象名        QString objectName = QString("comlist%1").arg(p);        // 查找對象        QLineEdit *comlist = this->findChild<QLineEdit *>(objectName);        if(comlist) {            comlist->setText(info.portName());        }        p++;    }    //設置UI頁面的默認Index    ui->bo_num->setCurrentIndex(5);    ui->data_num->setCurrentIndex(3);    ui->check_num->setCurrentIndex(2);    ui->stop_num->setCurrentIndex(0);}MainWindow::~MainWindow(){    delete ui;    if(mthread->isRunning())    {        mthread->quit();        mthread->wait();        delete[] mthread;//        delete[] comthread;    }}void MainWindow::slots_already_send_byte(QString com, int num){    int com_num = com.remove(snap).toInt();    QString objectname = QString("send_byte_") + QString::number(com_num);    QLabel *label = this->findChild<QLabel *>(objectname);    if(label)    {        label->setText(QString::number(num));    }    qDebug()<<com<<"已發送"<<num;}void MainWindow::slots_already_receive_byte(QString com, int num){    int com_num = com.remove(snap).toInt();    QString objectname = QString("recv_byte_") + QString::number(com_num);    QLabel *label = this->findChild<QLabel *>(objectname);    if(label)    {        label->setText(QString::number(num));    }    qDebug()<<com<<"已接收"<<num;}void MainWindow::slots_result(QString com, int num){    int com_num = com.remove(snap).toInt();    QString objectname = QString("list_result_") + QString::number(com_num);    QPushButton *button = this->findChild<QPushButton *>(objectname);    if(button)    {        if(1 == num)        {            button->setText("通過");            button->setStyleSheet("background-color:rgb(27,167,132)");        }        else        {            button->setText("失敗");            button->setStyleSheet("background-color:rgb(238, 72, 99)");        }    }    qDebug()<<com<<"測試結果(0代表失敗 1,代表成功)"<<num;}void MainWindow::slots_already_receive_string(QString com, QString string){    int com_num = com.remove(snap).toInt();    QString objectname = QString("recv_date_") + QString::number(com_num);    QLineEdit *Edit = this->findChild<QLineEdit *>(objectname);    if(Edit)    {        Edit->setText(string);    }    qDebug()<<com<<"已接收字符串"<<string;}void MainWindow::send_com_signal(QString com, bool DTR, bool DCD, bool DSR, bool RNG, bool RTS, bool CTS, bool STD, bool SRD){    int com_num = com.remove(snap).toInt();    {        if(DTR)        {            QString objectname = QString("DTR_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(DCD)        {            QString objectname = QString("DCD_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(DSR)        {            QString objectname = QString("DSR_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(RNG)        {            QString objectname = QString("RNG_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(RTS)        {            QString objectname = QString("RTS_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(CTS)        {            QString objectname = QString("CTS_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(STD)        {            QString objectname = QString("STD_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }        if(SRD)        {            QString objectname = QString("SRD_") + QString::number(com_num);            QToolButton *ToolButton = this->findChild<QToolButton *>(objectname);            if(ToolButton)            {                ToolButton->setStyleSheet("background-color:rgb(240, 124, 130)");            }        }    }    qDebug()<<"com"<<"DTRstate"<<"DCDstate"<<"DSRstate"<<"RINGRstate"<<"RTSstate"<<"CTSstate"<<"STDstate"<<"SRDstate";    qDebug()<<com<<DTR<<DCD<<DSR<<RNG<<RTS<<CTS<<STD<<SRD;}// 點擊進入串口回路測試void MainWindow::on_serial_test_clicked(){    // 判斷當前系統#ifdef Q_OS_WIN    snap = QString("COM");#elif defined(Q_OS_LINUX)    snap = QString("ttyS");#endif    int qserial_size = PortStringList.size();    bool open_test[qserial_size];    for (int i = 0; i < qserial_size; ++i) {        open_test[i] = true;    }    // 獲取串口等信息    QString Port = ui->port->currentText();    qint32 rate = ui->bo_num->currentText().toInt();    qint32 date = ui->data_num->currentText().toInt();    qint32 check_num = ui->check_num->currentIndex();    qint32 stop_num = ui->stop_num->currentIndex();//    qDebug()<<"檢查位:"<<check_num<<"停止位:"<<stop_num;    // TODO多com口同時測試  14個線程    mthread = new QThread[qserial_size];    /*    // comthread = new ComThread(Port,rate,date,check_num,stop_num);    // comthread = new ComThread[14](Port,rate,date,check_num,stop_num);    // ComThread * comthread = new ComThread[PortStringList.size()];//    comthread = new ComThread[qserial_size];    // 為每個元素分配對應的端口,并初始化ComThread對象數組//    for (int i = 0; i < qserial_size; ++i) {//        comthread[i] = ComThread(PortStringList.at(i));//    }*//*    for(int m = 0;m < qserial_size; m++)    {        // comthread[m] = ComThread(PortStringList.at(m));//        comthread.emplace_back(ComThread(PortStringList.at(m)));    }    {        ComThread(PortStringList.at(0)),        ComThread(PortStringList.at(1)),        ComThread(PortStringList.at(2)),        ComThread(PortStringList.at(3)),        ComThread(PortStringList.at(4)),        ComThread(PortStringList.at(5)),        ComThread(PortStringList.at(6)),        ComThread(PortStringList.at(7)),        ComThread(PortStringList.at(8)),        ComThread(PortStringList.at(9)),        ComThread(PortStringList.at(10)),        ComThread(PortStringList.at(11)),        ComThread(PortStringList.at(12)),        ComThread(PortStringList.at(13)),    };*/    int i = 0;    foreach(QString com_e,PortStringList)    {        ComThread *comthread = new ComThread(com_e);        // qDebug()<<com_e;        // 移入線程//        comthread[i].moveToThread(&mthread[i]);        comthread->moveToThread(&mthread[i]);        mthread[i].start();        //關聯信號        if(open_test[i])        {//            connect(this,&MainWindow::sig_openPort,&comthread[i],&ComThread::slot_openPort);//            connect(this,&MainWindow::sig_recv_com_s,&comthread[i],&ComThread::slot_recv_com_s);            connect(this,&MainWindow::sig_openPort,comthread,&ComThread::slot_openPort);            connect(this,&MainWindow::sig_recv_com_s,comthread,&ComThread::slot_recv_com_s);            // 關聯返回信號            connect(comthread,&ComThread::already_receive_byte,this,&MainWindow::slots_already_receive_byte);            connect(comthread,&ComThread::already_receive_string,this,&MainWindow::slots_already_receive_string);            connect(comthread,&ComThread::already_send_byte,this,&MainWindow::slots_already_send_byte);            connect(comthread,&ComThread::result,this,&MainWindow::slots_result);            connect(comthread,&ComThread::send_com_signal,this,&MainWindow::send_com_signal);            open_test[i] = false;        }        qDebug()<<"main ThreaiD:"<<QThread::currentThreadId();        emit sig_recv_com_s(rate,date,check_num,stop_num);        emit sig_openPort();//        pool->start(comthread);        {            // 取消單個信號對所有串口的信號連接//            disconnect(this,&MainWindow::sig_openPort,&comthread[i],&ComThread::slot_openPort);//            disconnect(this,&MainWindow::sig_recv_com_s,&comthread[i],&ComThread::slot_recv_com_s);            disconnect(this,&MainWindow::sig_openPort,comthread,&ComThread::slot_openPort);            disconnect(this,&MainWindow::sig_recv_com_s,comthread,&ComThread::slot_recv_com_s);        }        i++;        // pool->waitForDone();        //        qDebug()<<"執行結束";//        QThread::sleep(1);        // mthread->quit();        // mthread[0].isFinished();    }    // 循環結束線程    for(int j = 0;j<PortStringList.size();j++)    {        if(mthread[j].isFinished())        {            // qDebug()<<"quit"<<j;            mthread[j].quit();            mthread[j].wait();        }        else        {            // qDebug()<<"wait"<<j;            mthread[j].quit();            mthread[j].wait();        }    }//    delete [] mthread;}

6.main.cpp

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    MainWindow w;    w.show();    return a.exec();}

八、問題解決

1.多線程中出現QObject: Cannot create children for a parent that is in a different thread

這個錯誤提示的實際意思是,不能在子線程中生成跨線程調用的成員。如果一個成員在父線程中被直接調用了,那么這個成員必須處在父線程中,強行在子線程中生成就會出現這個錯誤提示。jqv28資訊網——每日最新資訊28at.com

將在多線程中構造函數中new出來的變量,放到run中執行,因為構造函數是在主線程完成初始化的,線程所屬于不同的線程,就會出現此類錯誤。jqv28資訊網——每日最新資訊28at.com

解決此問題的關鍵將線程放到一個地方,例如子線程中的對串口的new定義。jqv28資訊網——每日最新資訊28at.com

2.munmap_chunk(): invalid pointer解決方案線程池釋放,程序崩潰

程序分析:將程序線程池取消自動釋放,結果程序確實沒有發生崩潰,可以繼續運行,所以分析斷定,程序崩潰為線程池析構時的問題。jqv28資訊網——每日最新資訊28at.com

展示關閉線程自動銷毀功能,同時程序中多次使用。jqv28資訊網——每日最新資訊28at.com

解決方案:檢查程序結束,或者異常結束資源銷毀問題。jqv28資訊網——每日最新資訊28at.com

3.循環發送信息,并沒有收到數據,而是最后一起收到數據

在發送數據之后,加入waitForReadyRead(10);函數,就會接受數據,此函數功能為等待接受,與其說等待,其實立馬就接受了數據。否則在測試當中出現了五次循環結束,一同接受數據的情況。jqv28資訊網——每日最新資訊28at.com

for(int i = 0;i<5;i++){    QString realbom = "realbom";    QByteArray send = realbom.toUtf8();    qDebug()<<send;    mSerialPort->write(send);//        QThread::sleep(1);    mSerialPort->waitForReadyRead(10); // 接受數據}

4.接受數據和發送數據格式不同,接受數據亂碼

  • 查詢是否是串口參數配置問題。我的確實是此問題,當時確實是玩完沒有想到,設置默認值之后,就可以
  • 設置正確的編碼轉換關系
QByteArray send = realbom.toUtf8();qDebug()<<send<<"Byte大小:"<<send.length();mSerialPort->write(send);QByteArray  Receivetext = mSerialPort->readAll();qDebug()<<"接收:"<<QString::fromUtf8(Receivetext)<<"Byte大小:"<<Receivetext.length();


jqv28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-25979-0.htmlQt串口回路信號讀取多線程14串口測試方案

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Java下跌,被C#逼近!Kotlin后生可畏

下一篇: 應用獲取客戶端真實IP

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 宁南县| 冕宁县| 邵武市| 淅川县| 大田县| 志丹县| 咸宁市| 泰州市| 子长县| 辽阳县| 察隅县| 于都县| 湘潭市| 习水县| 大兴区| 绥宁县| 崇阳县| 比如县| 多伦县| 灌南县| 花垣县| 云霄县| 麻阳| 桦甸市| 丽水市| 怀来县| 宝清县| 兴隆县| 茂名市| 湖州市| 富民县| 桑日县| 伊金霍洛旗| 宿松县| 柳河县| 瑞丽市| 卢龙县| 绿春县| 馆陶县| 游戏| 甘孜县|