Qt編寫串口通信程序全程圖文講解_第1頁
Qt編寫串口通信程序全程圖文講解_第2頁
Qt編寫串口通信程序全程圖文講解_第3頁
Qt編寫串口通信程序全程圖文講解_第4頁
Qt編寫串口通信程序全程圖文講解_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 Qt編寫串口通信程序全程圖文講解 2010-10-19 17:44:44分類: LINUX(說明:我們的編程環(huán)境是windows xp下,在Qt Creator中進(jìn)行,如果在Linux下或直接用源碼編寫,程序稍有不同,請(qǐng)自己改動(dòng)。)在Qt中并沒有特定的串口控制類,現(xiàn)在大部分人使用的是第三方寫的qextserialport類,我們這里也是使用的該類。我們可以去進(jìn)行下載,也可以去下載我上傳到網(wǎng)上的: 或 /bbs/read.php?tid=22847下載到的文件為:qextserialport-1.2win-alpha.

2、zip其內(nèi)容如下圖:我們?cè)趙indows下只需要使用其中的6個(gè)文件:qextserialbase.cpp和qextserialbase.h,qextserialport.cpp和qextserialport.h,win_qextserialport.cpp和win_qextserialport.h如果在Linux下只需將win_qextserialport.cpp和win_qextserialport.h 換為 posix_qextserialport.cpp和posix_qextserialport.h即可。第一部分:下面我們將講述編程的詳細(xì)過程,這里我們先給出完整的程序,然后到第二部分再進(jìn)

3、行逐句分析。1.打開Qt Creator,新建Qt4 Gui Application,工程名設(shè)置為mycom,其他使用默認(rèn)選項(xiàng)。(注意:建立的工程路徑不能有中文。)2.將上面所說的6個(gè)文件復(fù)制到工程文件夾下,如下圖。3.在工程中添加這6個(gè)文件。在Qt Creator中左側(cè)的文件列表上,鼠標(biāo)右擊工程文件夾,在彈出的菜單中選擇Add Existing Files,添加已存在的文件。如下圖:選擇工程文件夾里的那6個(gè)文件,進(jìn)行添加。如下圖。添加好后文件列表如下圖所示:4.點(diǎn)擊mainwindow.ui,在窗口上加入一個(gè)Text Browser,用來顯示信息。如下圖。5.在mainwindow.h的相應(yīng)

4、位置添加頭文件#include "win_qextserialport.h",添加對(duì)象聲明Win_QextSerialPort *myCom;添加槽函數(shù)聲明 void readMyCom();添加完后,如下圖。6.在mainwindow.cpp的類的構(gòu)造函數(shù)中添加如下語句。MainWindow:MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui:MainWindow)ui->setupUi(this);struct PortSettings myComSetting = BAUD9600,DATA_8

5、,PAR_NONE,STOP_1,FLOW_OFF,500;/定義一個(gè)結(jié)構(gòu)體,用來存放串口各個(gè)參數(shù)myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase:EventDriven);/定義串口對(duì)象,并傳遞參數(shù),在構(gòu)造函數(shù)里對(duì)其進(jìn)行初始化myCom ->open(QIODevice:ReadWrite);/以可讀寫方式打開串口connect(myCom,SIGNAL(readyRead(),this,SLOT(readMyCom();/信號(hào)和槽函數(shù)關(guān)聯(lián),當(dāng)串口緩沖區(qū)有數(shù)據(jù)時(shí),進(jìn)行讀串口操作在下面添

6、加readMyCom()函數(shù)的定義,添加如下代碼。void MainWindow:readMyCom() /讀串口函數(shù)QByteArray temp = myCom->readAll();/讀取串口緩沖區(qū)的所有數(shù)據(jù)給臨時(shí)變量tempui->textBrowser->insertPlainText(temp);/將串口的數(shù)據(jù)顯示在窗口的文本瀏覽器中添加完代碼后如下圖。此時(shí)如果運(yùn)行程序,已經(jīng)能實(shí)現(xiàn)讀取串口數(shù)據(jù)的功能了。我們將單片機(jī)采集的溫度信息由串口傳給計(jì)算機(jī),效果如下圖。這樣最簡(jiǎn)單的串口通信程序就完成了??梢钥吹剿恍枰尤霂仔写a即可,非常簡(jiǎn)單。第二部分:上一部分中已經(jīng)介紹了

7、實(shí)現(xiàn)最簡(jiǎn)單的串口接收程序的編寫,下面將對(duì)程序內(nèi)容進(jìn)行分析。1.首先應(yīng)說明操作串口的流程。步驟一:設(shè)置串口參數(shù),如:波特率,數(shù)據(jù)位,奇偶校驗(yàn),停止位,數(shù)據(jù)流控制等。步驟二:選擇串口,如windows下的串口1為“com1”,Linux下為“ttyS0”等,并打開串口。步驟三:讀或?qū)懘?。步驟四:關(guān)閉串口。(我們上一個(gè)程序沒有寫串口和關(guān)閉串口的功能,打開串口也是在構(gòu)造函數(shù)里完成的,因?yàn)槟侵皇菫榱擞米詈?jiǎn)單的方法完成串口程序的編寫。在后面我們將會(huì)對(duì)它進(jìn)行修改和完善。)2.下面我們將按照上面的操作串口的流程,講解第一個(gè)程序的編寫。第一,我們?cè)趯懗绦蛑?,?yīng)該瀏覽一下那6個(gè)文件,大概看一下它們里面都是什么

8、內(nèi)容,各個(gè)文件各個(gè)類之間有什么聯(lián)系。在win_qextserialport.cpp文件中,我們看它的最后一個(gè)構(gòu)造函數(shù),會(huì)發(fā)現(xiàn),串口可以在這里進(jìn)行初始化。 Win_QextSerialPort:Win_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase:QueryMode mode) Win_Handle=INVALID_HANDLE_VALUE;setPortName(name);setBaudRate(settings.BaudRate);setDataB

9、its(settings.DataBits);setStopBits(settings.StopBits);setParity(settings.Parity);setFlowControl(settings.FlowControl);setTimeout(settings.Timeout_Millisec);setQueryMode(mode);init();它共有三個(gè)參數(shù),其中第一個(gè)參數(shù)const QString & name,應(yīng)該是串口的名字,是QString類型,我們可以用串口1即“com1”,不用過多說明。下面我們主要研究第二個(gè)和第三個(gè)參數(shù)。第二,我們查看第二個(gè)參數(shù)的位置。在

10、Qt Creator的菜單中選擇Edit->Find/Replace->All projects,如下圖。在彈出的對(duì)話框中輸入要查找的內(nèi)容PortSettings,如下圖。點(diǎn)擊Search后,便能在下面顯示出整個(gè)工程中所有PortSettings的位置。如下圖。我們點(diǎn)擊第一條,可以看到在qextserialbase.h文件中有一個(gè)struct PortSettings,如下圖。我們雙擊這一條,進(jìn)入相應(yīng)的文件。如下圖。struct PortSettingsBaudRateType BaudRate;DataBitsType DataBits;ParityType Parity;Sto

11、pBitsType StopBits;FlowType FlowControl;long Timeout_Millisec;可以看到在這個(gè)結(jié)構(gòu)體里定義了串口初始化的各個(gè)參數(shù),而對(duì)于BaudRateType等類型的定義,我們?cè)谶@個(gè)結(jié)構(gòu)體的上面可以看到,它們是多個(gè)枚舉變量。如下圖。  這時(shí)我們便應(yīng)該明白了,這個(gè)結(jié)構(gòu)體便是實(shí)現(xiàn)串口參數(shù)設(shè)置的。第三,定義串口參數(shù)。BaudRateType BaudRate;波特率設(shè)置,我們?cè)O(shè)置為9600,即程序中用BAUD9600;DataBitsType DataBits;數(shù)據(jù)位設(shè)置,我們?cè)O(shè)置為8位數(shù)據(jù)位,即DATA_8;ParityType P

12、arity;奇偶校驗(yàn)設(shè)置,我們?cè)O(shè)置為無校驗(yàn),即PAR_NONE;StopBitsType StopBits;停止位設(shè)置,我們?cè)O(shè)置為1位停止位,即STOP_1;FlowType FlowControl;數(shù)據(jù)流控制設(shè)置,我們?cè)O(shè)置為無數(shù)據(jù)流控制,即FLOW_OFF;long Timeout_Millisec;延時(shí)設(shè)置,我們?cè)O(shè)置為延時(shí)500ms,即500;這樣便寫出了程序中的那句:struct PortSettings myComSetting = BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500;我們定義了一個(gè)結(jié)構(gòu)體變量myComSetting,并對(duì)其進(jìn)行了初

13、始化。第四,設(shè)置第三個(gè)參數(shù)。我們先按上面的方法找到它的定義位置,在qextserialbase.h中,如下圖。可以看到查詢模式也是枚舉變量,有兩個(gè)選項(xiàng),我們選擇第二個(gè)EventDriven,事件驅(qū)動(dòng)。到這里,我們就可以定義Win_QextSerialPort類的變量了,就是那句:myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase:EventDriven);它完成了串口的選擇和串口的初始化。第五,寫打開串口函數(shù)和讀串口函數(shù)。查看win_qextserialport.h文件,我們會(huì)發(fā)現(xiàn)Win_Qex

14、tSerialPort類繼承自QextSerialBase類。查看qextserialbase.h文件,我們會(huì)發(fā)現(xiàn)QextSerialBase類繼承自QIODevice 類。我們?cè)赒t的幫助中查看QIODevice 類,如下圖。其部分內(nèi)容如下圖??梢钥吹狡渲杏衑num OpenModeFlag  NotOpen, ReadOnly, WriteOnly, ReadWrite, ., Unbuffered ,virtual bool open ( OpenMode mode ),QByteArray readAll 

15、()等內(nèi)容。而下面的信號(hào)函數(shù)中有void readyRead ();它可以查看串口是否有新的數(shù)據(jù)傳來。所以,我們可以用這個(gè)類里的這些函數(shù)操作串口。如程序中的語句:myCom ->open(QIODevice:ReadWrite);/我們調(diào)用了其中的open函數(shù),用ReadWrite可讀寫的方式進(jìn)行打開串口,這個(gè)open函數(shù)在win_qextserialport.cpp中被重定義了connect(myCom,SIGNAL(readyRead(),this,SLOT(readMyCom();/我們關(guān)聯(lián)信號(hào)readyRead(),和自己寫的槽函數(shù)readMyCom(),當(dāng)串

16、口有數(shù)據(jù)傳來時(shí)進(jìn)行讀串口操作void MainWindow:readMyCom() /自己寫的讀串口函數(shù)QByteArray temp = myCom->readAll();/我們調(diào)用readAll()函數(shù),讀取串口中所有數(shù)據(jù),在上面可以看到其返回值是QByteArray類型ui->textBrowser->insertPlainText(temp);/調(diào)用insertPlainText()函數(shù),是窗口上的文本瀏覽器中連續(xù)輸出數(shù)據(jù),而不是每次寫數(shù)據(jù)前都清除以前的/數(shù)據(jù),可以在Qt的幫助里查看這個(gè)函數(shù)的說明這樣我們便寫完了所有的語句,最后只需要在mainwindow.h文件中加

17、入相應(yīng)的頭文件,對(duì)象聲明,函數(shù)聲明即可。      這里需要說明的是我們一定要學(xué)會(huì)查看文件和使用幫助文檔,將我們不懂得知識(shí)一點(diǎn)一點(diǎn)搞明白。第三部分:下面的程序在第一部分中所寫的程序上進(jìn)行了一些改進(jìn)。加入打開和關(guān)閉串口,發(fā)送數(shù)據(jù)等功能。1.加入了“打開串口”,“關(guān)閉串口”“傳送數(shù)據(jù)”三個(gè)按鈕,加入了一個(gè)行編輯框Line Edit。它們的命名如下:“打開串口”按鈕命名為:openMyComBtn“關(guān)閉串口”按鈕命名為:closeMyComBtn“傳送數(shù)據(jù)”按鈕命名為:sendMsgBtn要傳送數(shù)據(jù)的行編輯框命名為:sendMsgLineE

18、dit界面如下圖。2.在“打開串口”按鈕上右擊,選擇Go to slot選項(xiàng),然后選擇clicked()選項(xiàng),進(jìn)入它的單擊事件槽函數(shù)中,將上個(gè)程序中在構(gòu)造函數(shù)里寫的語句全部剪切到這里。然后加入幾句按鈕的狀態(tài)設(shè)置語句。如下:void MainWindow:on_openMyComBtn_clicked()struct PortSettings myComSetting = BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500;/定義一個(gè)結(jié)構(gòu)體,用來存放串口各個(gè)參數(shù)myCom = new Win_QextSerialPort("com1",m

19、yComSetting,QextSerialBase:EventDriven);/定義串口對(duì)象,并傳遞參數(shù),在構(gòu)造函數(shù)里對(duì)其進(jìn)行初始化myCom ->open(QIODevice:ReadWrite);/以可讀寫方式打開串口connect(myCom,SIGNAL(readyRead(),this,SLOT(readMyCom();/信號(hào)和槽函數(shù)關(guān)聯(lián),當(dāng)串口緩沖區(qū)有數(shù)據(jù)時(shí),進(jìn)行讀串口操作ui->openMyComBtn->setEnabled(false); /打開串口后“打開串口”按鈕不可用ui->closeMyComBtn->setEnabled(t

20、rue); /打開串口后“關(guān)閉串口”按鈕可用ui->sendMsgBtn->setEnabled(true); /打開串口后“發(fā)送數(shù)據(jù)”按鈕可用在構(gòu)造函數(shù)里也添加幾句按鈕初始狀態(tài)設(shè)置語句,如下:MainWindow:MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui:MainWindow)ui->setupUi(this);ui->closeMyComBtn->setEnabled(false); /開始“關(guān)閉串口”按鈕不可用ui->sendMsgBtn->

21、;setEnabled(false); /開始“發(fā)送數(shù)據(jù)”按鈕不可用更改后程序如下圖所示: 這時(shí)運(yùn)行程序,效果如下:3.按上面的方法進(jìn)入“關(guān)閉串口”按鈕和“發(fā)送數(shù)據(jù)”按鈕的單擊事件的槽函數(shù),更改如下。void MainWindow:on_closeMyComBtn_clicked()      /關(guān)閉串口槽函數(shù)myCom->close(); /關(guān)閉串口,該函數(shù)在win_qextserialport.cpp文件中定義ui->openMyComBtn->setEnabled(true); /

22、關(guān)閉串口后“打開串口”按鈕可用ui->closeMyComBtn->setEnabled(false); /關(guān)閉串口后“關(guān)閉串口”按鈕不可用ui->sendMsgBtn->setEnabled(false); /關(guān)閉串口后“發(fā)送數(shù)據(jù)”按鈕不可用/*/void MainWindow:on_sendMsgBtn_clicked()       /發(fā)送數(shù)據(jù)槽函數(shù)myCom->write(ui->sendMsgLineEdit->text().toAscii();/以ASCII碼形

23、式將行編輯框中的數(shù)據(jù)寫入串口程序如下圖: 最終效果如下:(將數(shù)據(jù)x發(fā)送給單片機(jī),單片機(jī)返回you send message is : x) 第四部分:本文一開始先講解對(duì)程序的改進(jìn),在文章最后將要講解一些重要問題。1.在窗口中加入一些組合框Combo Box,它們的名稱及條目如下:串口:portNameComboBox,條目為:COM1,COM2波特率:baudRateComboBox,條目為:9600,115200數(shù)據(jù)位:dataBitsComboBox,條目為:8,7校驗(yàn)位:parityComboBox,條目為:無,奇,偶停止位:stopBitsComboBox,條目為:

24、1,2(注:在窗口上的Combo Box上雙擊,在彈出的對(duì)話框上按“+”號(hào),可添加條目。我們只是為了演示,所以只加了這幾個(gè)條目,你可以根據(jù)自己的需要添加。)改好的窗口如下所示:2.更改“打開串口”按鈕的單擊事件槽函數(shù)。void MainWindow:on_openMyComBtn_clicked()QString portName = ui->portNameComboBox->currentText(); /獲取串口名myCom = new Win_QextSerialPort(portName,QextSerialBase:EventDriven);/定義串口對(duì)象,并

25、傳遞參數(shù),在構(gòu)造函數(shù)里對(duì)其進(jìn)行初始化myCom ->open(QIODevice:ReadWrite); /打開串口if(ui->baudRateComboBox->currentText()=tr("9600") /根據(jù)組合框內(nèi)容對(duì)串口進(jìn)行設(shè)置myCom->setBaudRate(BAUD9600);else if(ui->baudRateComboBox->currentText()=tr("115200")myCom->setBaudRate(BAUD115200);/設(shè)置波特率if(ui->

26、;dataBitsComboBox->currentText()=tr("8")myCom->setDataBits(DATA_8);else if(ui->dataBitsComboBox->currentText()=tr("7")myCom->setDataBits(DATA_7);/設(shè)置數(shù)據(jù)位if(ui->parityComboBox->currentText()=tr("無")myCom->setParity(PAR_NONE);else if(ui->parityCom

27、boBox->currentText()=tr("奇")myCom->setParity(PAR_ODD);else if(ui->parityComboBox->currentText()=tr("偶")myCom->setParity(PAR_EVEN);/設(shè)置奇偶校驗(yàn)if(ui->stopBitsComboBox->currentText()=tr("1")myCom->setStopBits(STOP_1);else if(ui->stopBitsComboBox->

28、currentText()=tr("2")myCom->setStopBits(STOP_2);/設(shè)置停止位myCom->setFlowControl(FLOW_OFF); /設(shè)置數(shù)據(jù)流控制,我們使用無數(shù)據(jù)流控制的默認(rèn)設(shè)置myCom->setTimeout(500); /設(shè)置延時(shí)connect(myCom,SIGNAL(readyRead(),this,SLOT(readMyCom();/信號(hào)和槽函數(shù)關(guān)聯(lián),當(dāng)串口緩沖區(qū)有數(shù)據(jù)時(shí),進(jìn)行讀串口操作ui->openMyComBtn->setEnabled(false); /打開串口

29、后“打開串口”按鈕不可用ui->closeMyComBtn->setEnabled(true); /打開串口后“關(guān)閉串口”按鈕可用ui->sendMsgBtn->setEnabled(true); /打開串口后“發(fā)送數(shù)據(jù)”按鈕可用ui->baudRateComboBox->setEnabled(false); /設(shè)置各個(gè)組合框不可用ui->dataBitsComboBox->setEnabled(false);ui->parityComboBox->setEnabled(false);ui->stopBitsCombo

30、Box->setEnabled(false);ui->portNameComboBox->setEnabled(false);這里我們先獲取串口的名稱,然后調(diào)用另一個(gè)構(gòu)造函數(shù)對(duì)myCom進(jìn)行定義,這個(gè)構(gòu)造函數(shù)里沒有串口的設(shè)置參數(shù)。然后打開串口。然后獲取串口的設(shè)置數(shù)據(jù),用setBaudRate();等一系列函數(shù)進(jìn)行串口的設(shè)置,這些函數(shù)都在win_qextserialport.cpp文件中定義,如下圖。 看完前面幾部分的內(nèi)容,對(duì)于這幾個(gè)函數(shù)應(yīng)該很好理解,這里不再解釋。在最后我們對(duì)添加的那幾個(gè)組合框進(jìn)行了不可用設(shè)置,使其在串口打開的情況下不能選擇。程序如下:3.更改“關(guān)閉

31、串口”按鈕單擊事件的槽函數(shù)。void MainWindow:on_closeMyComBtn_clicked()myCom->close();ui->openMyComBtn->setEnabled(true); /關(guān)閉串口后“打開串口”按鈕可用ui->closeMyComBtn->setEnabled(false); /關(guān)閉串口后“關(guān)閉串口”按鈕不可用ui->sendMsgBtn->setEnabled(false); /關(guān)閉串口后“發(fā)送數(shù)據(jù)”按鈕不可用ui->baudRateComboBox->setEnabled(true);

32、0;/設(shè)置各個(gè)組合框可用ui->dataBitsComboBox->setEnabled(true);ui->parityComboBox->setEnabled(true);ui->stopBitsComboBox->setEnabled(true);ui->portNameComboBox->setEnabled(true);這里只是加入了一些使組合框在“關(guān)閉串口”按鈕按下后變?yōu)榭捎玫恼Z句。程序如下: 4.更改main.cpp文件。#include#include /加入頭文件#include "mainwind

33、ow.h"int main(int argc, char *argv)QApplication a(argc, argv);QTextCodec:setCodecForTr(QTextCodec:codecForLocale();/使程序可處理中文MainWindow w;w.show();return a.exec();因?yàn)樯厦娴某绦蛑杏玫搅酥形模瑸榱四苁钩绦蜃R(shí)別中文,我們需要在主函數(shù)中加入這些語句。程序如下: 5.運(yùn)行程序。打開后程序界面如下。 正常發(fā)送1后效果如下。 設(shè)置為“奇校驗(yàn)”,發(fā)送完1的效果如下圖。(接收到的是亂碼) 到這里,整個(gè)

34、程序就寫完了。重要問題說明:(下面所說的第一個(gè)程序是指第一部分中寫的那個(gè)程序,第二個(gè)程序是指第三部分更改完后的程序,第三個(gè)程序是指第四部分更改完后的程序。)問題一:更改第一個(gè)程序中的代碼。struct PortSettings myComSetting = BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500;myCom = new Win_QextSerialPort("com1",myComSetting,QextSerialBase:EventDriven);這兩行代碼如果換為下面一行:myCom = new Win_QextSerialPort(&qu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論