使用QT5自帶的QSerialPort和QSerialPortInfo進行串口開發時,程序重啟或長時間運行時,有時會讀取不到串口數據,一次讀取不到后,后面無論如何嘗試,都讀取不到.
為了解決這個bug, 使用qextserialport來代替進行開發.
參考連接: https://blog.csdn.net/g1036583997/article/details/44805217/
https://blog.csdn.net/u010580186/article/details/51595227
文件下載地址:
http://sourceforge.net/projects/qextserialport/files/
下載后的文件為: qextserialport-1.2win-alpha.zip
下載后進行解壓,會得到相應的linux和windows開發的文件.
用到的文件:
linux下:qextserialbase.cpp qextserialbase.h posix_qextserialport.cpp posix_qextserialport.h
windows下:qextserialbase.cpp qextserialbase.h win_qextserialport.cpp win_qextserialport.h
3.打開Qt Creator集成開發環境,新建工程Qt4 Gui Application ,工程名為com ,其他默認即可。
4.將上述linux下需要用到的4個文件拷貝至com工程目錄下,然后將該4個文件添加至工程。
5.將整個工程編譯,會報錯如下:error: 'struct PortSettings' has no member named 'Timeout_Sec'
錯誤所在函數為 setTimeout(Settings.Timeout_Sec, Settings.Timeout_Millisec);
我們直接將第一個參數刪除即可,即為 setTimeout(Settings.Timeout_Millisec);重新編譯工程成功。
6.點擊mainwindow.ui,在窗口中添加如下幾個控件,因控件較少,同時為了操作方便,我們保持各部件的屬性為默認值
Text Browser 部件用來顯示接收到的數據
Line Edit部件用來輸入要發送的數據
Push Button按鈕用來發送數據
7.在mainwindow.h文件中進行對象及函數聲明
7-1.添加頭文件包含#include "posix_qextserialport.h"#include <QTimer> //控制串口讀寫需要用到定時器 【此次不同於windows下的開發,非常重要】
7-2.在private中聲明對象Posix_QextSerialPort *myCom; //串口
QTimer *readTimer; //定時器 【此次不同於windows下的開發,非常重要】
7-3.聲明私有槽函數:private slots:
void on_pushButton_clicked(); //“發送數據”按鈕 槽函數
void readMyCom(); //讀取串口 槽函數
8.在mainwindow.cpp文件中添加實現代碼在構造函數中添加代碼,完成后,構造函數內容如下:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//myCom = new Win_QextSerialPort("COM1",QextSerialBase::EventDriven);
//【windows下使用】定義串口對象,指定串口名和查詢模式,這里使用事件驅動EventDriven
myCom = new Posix_QextSerialPort("/dev/ttyUSB0",QextSerialBase::Polling);
//【linux下使用】定義串口對象,指定串口名和查詢模式,這里使用Polling,若報錯,拔插USB //【此次不同於windows下的開發,非常重要】
myCom ->open(QIODevice::ReadWrite); //以讀寫方式打開串口
myCom->setBaudRate(BAUD9600); //波特率設置,我們設置為9600
myCom->setDataBits(DATA_8); //數據位設置,我們設置為8位數據位
myCom->setParity(PAR_NONE); //奇偶校驗設置,我們設置為無校驗
myCom->setStopBits(STOP_1); //停止位設置,我們設置為1位停止位
myCom->setFlowControl(FLOW_OFF); //數據流控制設置,我們設置為無數據流控制
myCom->setTimeout(200); //延時設置,我們設置為延時200ms,如果設置為500ms的話,會造成程序無響應,原因未知
//connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));
//【windows下使用】信號和槽函數關聯,當串口緩沖區有數據時,進行讀串口操作,linux不支持,只能用定時
readTimer = new QTimer(this); //設置讀取計時器
readTimer->start(100); //設置延時為100ms
connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));
//【linux下使用】信號和槽函數關聯,當達到定時時間時,進行讀串口操作
//【以上三條與君不同於windows下的開發,非常重要】}
實現槽函數:
void MainWindow::readMyCom() //讀取串口數據並顯示出來
{ QByteArray temp = myCom->readAll(); //讀取串口緩沖區的所有數據給臨時變量temp
ui->textBrowser->insertPlainText(temp); //將串口的數據顯示在窗口的文本瀏覽器中
}
void MainWindow::on_pushButton_clicked() //發送數據
{ myCom->write(ui->lineEdit->text().toAscii()); //以ASCII碼形式將數據寫入串口,在Qt5中使用toLatin1}
9.編譯工程,運行程序成功。
ps:本實例完成了linux下最基本的QT串口實例,如需擴展其他功能(如:設置波特率、串口號、自定義發送內容),請參考網上其他教程 后續我會將本程序移植到基於linux+arm的開發板上運行。