QT串口編程


  我用的是QT5.12,自帶串口類,類名為

QSerialPort

  需要包含的頭文件:

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

  另外在.pro文件中要加入下面這一句,否則編譯的時候會報錯,參見:QT編譯報錯,LNK2019:無法解析的外部符號

QT += serialport

myserial.cpp

#include "myserial.h"

MySerial::MySerial()
{
}

MySerial::~MySerial()
{
    if(isOpen()) {
        close();
    }
}

/**
 * \brief 串口初始化
 *
 * \param[in] port_name:串口名,需與設備管理器上的COM口一致,如"COM1"
 * \param[in] baudrate:波特率
 *              #1200
 *              #2400
 *              #4800
 *              #9600
 *              #19200
 *              #38400
 *              #57600
 *              #115200
 * \param[in] bits:數據位
 *              #{5, 6, 7, 8}
 * \param[in] parity:校驗位
 *              #'n'/'N':無校驗
 *              #'e'/'E':偶校驗
 *              #'o'/'O':奇校驗
 *              #'0':0校驗,或space parity,校驗位始終為0
 *              #'1':1校驗,或mark parity,校驗位始終為1
 * \param[in] stop:停止位
 *              #{"1", "1.5", "2"}
 * \param[in] flow:流控
 *              #'n'/'N':不使用流控
 *              #'h'/'H':硬件流控
 *              #'s'/'S':軟件流控
 *
 * \retval 成功返回0,失敗返回-1
 */
int MySerial::MySrtialInit(QString port_name, int baudrate, int bits, char parity, QString stop, char flow)
{
    setPortName(port_name);

    //檢查串口是否已經打開
    if(isOpen()) {
        qDebug() << port_name << " is opened";
        return -1;
    }

    //打開串口
    if(!open(QIODevice::ReadWrite)) {
        qDebug() << port_name << "open failed";
        return -1;
    }

    //設置波特率和讀寫方向,可以傳入第2個參數設置讀寫方向,默認值就是可讀可寫
    setBaudRate(QSerialPort::BaudRate(baudrate));

    //設置數據位
    setDataBits(QSerialPort::DataBits(bits));

    //設置校驗位
    switch (parity) {
        case 'n':
        case 'N':
            setParity(QSerialPort::NoParity);  //無校驗
        break;

        case 'e':
        case 'E':
            setParity(QSerialPort::EvenParity);  //偶校驗
        break;

        case 'o':
        case 'O':
            setParity(QSerialPort::OddParity);  //奇校驗
        break;

        case '0':
            setParity(QSerialPort::SpaceParity);  //0校驗
        break;

        case '1':
            setParity(QSerialPort::MarkParity);  //1校驗
        break;

        default:
            return -1;
    }

    //設置停止位
    if (stop == "1") {
        setStopBits(QSerialPort::OneStop);  //1位停止位
    } else if (stop == "1.5") {
        setStopBits(QSerialPort::OneAndHalfStop);  //1.5位停止位
    } else if (stop == "2") {
        setStopBits(QSerialPort::TwoStop);  //2位停止位
    } else {
        return -1;
    }

    //設置流控
    switch (flow) {
        case 'n':
        case 'N':
            setFlowControl(QSerialPort::NoFlowControl); //無流控
        break;

        case 'h':
        case 'H':
            setFlowControl(QSerialPort::HardwareControl); //硬件流控
        break;

        case 's':
        case 'S':
            setFlowControl(QSerialPort::SoftwareControl); //軟件流控
        break;

        default:
            return -1;
    }

    //連接信號槽
    connect(this, SIGNAL(readyRead()), this, SLOT(receiver()));

    return 0;
}

/**
 * \brief 數據接收函數
 */
void MySerial::receiver(void)
{
    QString dat = readAll();
    qDebug() << "read data:" << dat;
}

myserial.h

#ifndef MYSERIAL_H
#define MYSERIAL_H

#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>

//如果不繼承自QSerialPort也要繼承自QObject,因為要使用信號與槽
class MySerial : public QSerialPort
{
    Q_OBJECT
private slots:
    void receiver(void);
public:
    MySerial();
    ~MySerial();
    int MySrtialInit(QString port_name, int baudrate, int bits, char parity, QString stop, char flow); //串口初始化
};

#endif // MYSERIAL_H

main.cpp

#include <QCoreApplication>
#include <QThread>
#include "myserial.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MySerial serial;
    if (0 == serial.MySrtialInit("COM3", 115200, 8, 'N', "1", 'N')) {
        while (true) {
            serial.write("Hello\r\n");
            //serial.flush(); //我以為刷新緩沖區后數據就能立馬發送出去,但好像並非如此,原因尚且未知
            serial.waitForBytesWritten();   //等待寫入完成
            QThread::sleep(1);
        }
    }

    return a.exec();
}

  程序運行的效果就是,每隔1S向外發送“Hello\r\n”,收到的數據也會打印出來(不會立馬打印出來,要等sleep結束)

對比總結

  一般的平台自帶的串口的校驗位沒有0校驗和1校驗,並且QT自帶的串口可以選擇1.5個停止位,這在一般的平台上是不支持的。但是QT自帶的串口可以選擇的波特率不多,不過常用的幾個波特率都有。

獲取可用的串口

  

    QList<QSerialPortInfo> info = QSerialPortInfo::availablePorts();
    for (int i = 0; i < info.length(); i++) {
        qDebug() << info[i].portName();
    }

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM