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