1. 程式人生 > >Qt實現串列埠通訊總結

Qt實現串列埠通訊總結

注意: Qt5釋出之前,Qt實現串列埠通訊一般是採用第三方類庫qextserialport。Qt5釋出後自帶了QtSerialPort 能夠支援串列埠通訊。

1、Qextserialport類介紹

     在Qt5之前的版本中並沒有特定的串列埠控制類,現在大部分人使用的是第三方寫的qextserialport類,本文章主要是講解怎樣利用此類實現串列埠通訊。

2、檔案下載地址:

3、檔案內容:

    3.1.下載到的檔案為qextserialport-1.2win-alpha ,解壓並開啟後其內容如下。

  

(1)doc資料夾中的檔案內容是QextSerialPort類和QextBaseType的簡單的說明,我們可以使用記事本程式將它們開啟。

(2)examples資料夾中是幾個例子程式,可以看一下它的原始碼,不過想執行它們好像會出很多問題啊。

(3)html資料夾中是QextSerialPort類的使用文件。

(4)然後就是剩下的幾個檔案了。其中qextserialenumerator.cpp及qextserialenumerator.h檔案中定義的QextSerialEnumerator類是用來獲取平臺上可用的串列埠資訊的。不過,這個類好像並不怎麼好用,而且它不是我們關注的重點,所以下面就不再介紹它了。

 (5)qextserialbase.cpp和qextserialbase.h檔案定義了一個QextSerialBase類,win_qextserialport.cpp和win_qextserialport.h檔案定義了一個Win_QextSerialPort類,posix_qextserialport.cpp和posix_qextserialport.h檔案定義了一個Posix_QextSerialPort類,qextserialport.cpp和qextserialport.h檔案定義了一個QextSerialPort類。這個QextSerialPort類就是我們上面所說的那個,它是所有這些類的子類,是最高的抽象,它遮蔽了平臺特徵,使得在任何平臺上都可以使用它。

                                                             

在Windows下是:

qextserialbase.cpp和qextserialbase.h 以及win_qextserialport.cpp和win_qextserialport.h

在Linux下是:

qextserialbase.cpp和qextserialbase.h 以及posix_qextserialport.cpp和posix_qextserialport.h

而在Windows下我們可以使用事件驅動EventDriven方式,也可以使用查詢Polling方式,但是在Linux下我們只能使用查詢Polling方式。

4、串列埠通訊的實現

   4.1  宣告串列埠物件 :

Win_QextSerialPort  *myCom;      //Windows系統內
Posix_QextSerialPort *myCom;      //Linux系統內

  4.2 串列埠定義:

//Windows中有兩種查詢模式,一種polling模式,一種EventDriven模式
myCom = new Win_QextSerialPort("COM1",QextSerialBase::Polling);                 //
myCom = new Win_QextSerialPort("COM1",QextSerialBase::EventDriven);
//Linux中只有Polling模式
myCom = new Posix_QextSerialPort("/dev/ttyS0",QextSerialBase::Polling);

    事件驅動方式EventDriven就是使用事件處理串列埠的讀取,一旦有資料到來,就會發出readyRead()訊號,我們可以關聯該訊號來讀取串列埠的資料。在事件驅動的方式下,串列埠的讀寫是非同步的,呼叫讀寫函式會立即返回,它們不會凍結呼叫執行緒。

    查詢方式Polling則不同,讀寫函式是同步執行的,訊號不能工作在這種模式下,而且有些功能也無法實現。但是這種模式下的開銷較小。我們需要自己建立定時器來讀取串列埠的資料。

    在Windows下支援以上兩種模式,而在Linux下只支援Polling模式。

  4.3 串列埠開啟模式

myCom ->open(QIODevice::ReadWrite);    //開啟模式
QIODevice::Unbuffered 0x0020 描述
QIODevice::NotOpen 0x0000
QIODevice::ReadOnly 0x0001
QIODevice::WriteOnly 0x0002
QIODevice::ReadWrite ReadOnly | WriteOnly
QIODevice::Append 0x0004
QIODevice::Truncate 0x0008
QIODevice::Text 0x0010

4.4 串列埠的配置函式

複製程式碼
myCom->setBaudRate(BAUD9600);          //波特率設定,我們設定為9600
myCom->setDataBits(DATA_8);            //資料位設定,我們設定為8位資料位
myCom->setParity(PAR_NONE);           //奇偶校驗設定,我們設定為無校驗
myCom->setStopBits(STOP_1);            //停止位設定,我們設定為1位停止位
myCom->setFlowControl(FLOW_OFF);      //控制流

myCom->setTimeout(long);              //設定時間間隔
複製程式碼

    setTimeout(long)引數決定了Polling查詢模式的讀取串列埠的速度。

4.5 串列埠工作

connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));    //EventDriven模式下才能觸發readyRead()訊號
connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));  //Polling模式定時器觸發timeout()信

4.6 串列埠讀取資料

QByteArray temp = myCom->readAll();    //返回讀取的位元組
int byteLen = myCom->bytesAvailable(); //返回串列埠緩衝區位元組數

4.7 串列埠寫資料

myCom -> Write(const char * data, qint64 maxSize );          //
myCom -> Write(const char * data );                          //
myCom -> Write(const QByteArray & byteArray);                //
int byteLen = myCom->bytesToWrite();                        //輸出寫資料的位元組數
//bytesWritten()訊號函式來獲取已經發送的資料的大小。

5、Qt5以後版本QSerialPort介紹

5.1  .pro檔案內需要加上如下程式碼

QT += serialport               //加在第一行或者第二行
複製程式碼
#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    read_port = new mythread(this);
    connect(this->read_port, SIGNAL(read_port_data()), this,  SLOT(display_data()));
}

Dialog::~Dialog()
{
    //delete this->my_serialport;
    delete ui;
}

void Dialog::on_pushButton_clicked()                   //open serial,開啟串列埠
{
    this->read_port->start();
}

void Dialog::display_data()                            //顯示資料
{
    ui->textBrowser->setText(this->read_port->requestData);
}