文/鄭忠楷 蔣學程 羅志灶
Qt是一個跨平臺的C++圖形用戶界面應用程序框架。它提供給應用程序開發(fā)者建立藝術級的圖形用戶界面所需的所用功能。Qt是完全面向對象的,很容易擴展,并且允許真正地組件編程.由挪威TrollTech公司出品,開放源代碼,完全面向對象,模塊化程度高,可重用性好,容易擴展,允許真正的組件編程,提供了信號/槽機制,替代回調函數,使組件間信號信號傳遞更安全、簡單,應用非常廣泛。QT還提供了多個C++類;Qt對各個模塊進行了良好的封裝,使各模塊可重用性較好;優(yōu)良的跨平臺特性,使用Qt類編寫的程序可以實現“一次編碼,到處編譯”,極大的降低了跨平臺開發(fā)的難度;支持Windows,Linux,Solaris,Su-nOS,FreeBSD,BSD/OS,SCO,AIX,OS390,QNX 等操作系統,面向對象很容易擴展。Qt 提供了一種稱為signals/slots 的安全類型來替代callback,具有良好的封裝機制,可重用性較好。同時包含近700API類庫,允許真正的組件編程,是一種開源軟件,使用起來簡便且高效,具有良好的可移植性,目前主流的具有移植性的GUIAPI開發(fā)包有miniGUI,Qt,OpenGUI。但是在自動化應用程序開發(fā)時,QT忘記提供給應用程序開發(fā)者一個很重要的工具—串口類,畢竟大多數單片機還是使用串口和上位機軟件完成通信的。在MFC/BorlandC的可視化程序開發(fā)工具里有都提供一個標準串口的控件,使我們十分快捷方便的開發(fā)出串口應用程序。因此我們有必要討論一下如何在QT Creator下進行串口應用程序的開發(fā)。
圖1
在數字信號傳輸中只有 “1”和“0”,從電平上而言也就是只有 “高電平”、“低電平”;這些“高電平”、“低電平”如果一塊兒同時在多根導線上傳輸,同時組成1組二進制數,那就是我們所說的并行傳輸;并行傳輸具有同時多個位的特點,但是在遠距離通信、無線通信上;由于物理條件的限制,我們目前還是大量采用串行傳輸;也就是把“1”和“0”逐個排列組成一串有序的序列進行傳輸。因為,從上面所說的可以看出,并行傳輸需要的線材多,不能無線通信,而且關鍵的一點是 — 多根線材及各自的分布參數決定了它們的每位延時特性不能完全一致,這在高速數據傳輸時是不能繞開的一個大缺點。因此實際應用中出現了串行通信方式。
圖2:窗口設計結構
圖3
采用串行通信時,每一位何時采樣--何時確定它是“1”和“0”就很關鍵;如果我們在傳輸“1”和“0”的同時傳輸一個時鐘信號,標明它的時間,這樣的串行傳輸我們就把它叫做同步傳輸,常見的有 SPI、I2C等協議。
圖1為同步串口時序——利用同時傳輸的時鐘(下降沿、粗點劃線時刻)確定每位何時采樣——何時確定它是“1”和“0”。
我們也可以預先約定好——每隔固定的時間間隔傳輸不同的位,利用一個序列的“1”和“0”他們各自所在的時間位置自身來確定它的時間點,這樣的串行傳輸我們就把它叫做異步傳輸,如RS232/RS485協議,那這樣為了我們在接收端能很好的與發(fā)送端時間一致,我們就要約定一個固定的時間間隔——這就叫做波特率——每秒傳送了多少個位,它的單位是bps(每秒發(fā)送多少位)。 相比于同步串行通信,異步串行通信不需要傳輸同步時鐘,又具有較好的抗干擾能力,這在通信端口有限或者遠距離傳輸時能夠 較好的節(jié)省資源。異步串行通信中非常重要的一點就是波特率的約定,因為異步通信沒有單獨用于傳輸時鐘信號的連接線,收發(fā)端對于每位“1”和“0”占用的時間要有著十分明確的規(guī)定—波特率。同時,在PC上通用異步串行口有著專門的一個地址“串口號”—用來區(qū)分多個UART口,常見的有 “UART0”~ “UART15”。具體每臺計算機的“串口號”分配我們可以從“桌面”-“我的電腦”-“右鍵”-“屬性”-“設備管理器”-“端口(COM)”中看到。
因為在QT Creator中不像在MFC/BorlandC的可視化程序開發(fā)工具中有現成的API控件可以供異步串口使用,所以我們需要自行準備額外的一些輔助文件,這些文件可以從https://sourceforge.net/projects/qextserialport/files/下載 ;在windoews平臺下需要以下六個文件:qextserialbase.cpp、qextserialbase.h、qextserialport.cpp、qextserialport.h、win_qextserialport.cpp、win_qextserialport.h。下載好文件后把它們統一拷貝到QT即將建立工程的文件夾--即“當前文件夾”下。
打開QT Creator選擇新建一個工程,具體可以根據用戶需要選擇是“窗體應用程序”還是“控制臺應用程序”。目前我們大多數情況下選擇開發(fā)“窗體應用程序”便于用戶操作。在左側“項目”的“源文件”和“頭文件”中對應添加剛才下載的六個文件,然后再在界面文件“.ui”上添加一個“spinBox”控件 和3個“PushButton”控件 ,分別用于選擇等下將要控制的“串口號”和“打開”、“ 關閉”串口;以及發(fā)送數據。 接著再在窗體上添加“textBrowser”、“ textEdit”兩個控件用于顯示接收到的串口信息和編輯準備發(fā)送的串口信息。如圖2所示。
隨后我們就可以在主文件 “mainwindow.h”中添加#include "win_qextserialport.h",添加槽函數聲明 void readMyCom();在主文件中“mainwindow.cpp” 添加對象聲明Win_QextSerialPort *myCom; struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500};修改“打開”按鈕控件的槽函數了,在其中編寫
//信號和槽函數關聯,當串口緩沖區(qū)有數據時,進行讀串口操作(如圖3)。
這樣成功打開串口后QT程序會給出一個對話框讓用戶確認打開了“串口7”。
我們可以通過修改myComSetting中的參數來修改諸如“波特率”、“數據位”、“校驗位”、“停止位”、“硬件流控制”、“延時”等等具體的串口參數,以便調整有關串口的其他的應用程序開發(fā);例如BAUD9600表示波特率設定為9600,DATA_8表示數據位為8位,PAR_NONE表示沒有采用寄偶校驗位,FLOW_OFF表示關閉硬件流控制,500表示延時500ms。同時, 修改主文件“mainwindow.cpp”中”發(fā)送”按鈕的槽函數如下:
myCom->write(ui->textEdit->text().toAscii()); //把文本編輯器內容發(fā)送到串口
增加主文件“mainwindow.cpp”中一個接收串口消息槽函數如下:
這樣就可以在接收端顯示接收到的文本信息了。
圖4
圖5
右鍵點擊“我的電腦”-“屬性”-“設備管理器”可以看到如圖4所示界面。
從中我們可以得知計算機上被我們使用“USB-串口”設備的方式,即通過采用PL2303芯片組的方式添加了2個串口,串口號分別是“COM4”和“COM6”。我們將“COM4”和“COM6”設備的“TX”線和“RX”線分別互相連接,再在2個應用程序中分別打開“COM4”和“COM6”,然后在一個程序的發(fā)送端文本編輯欄輸入想要發(fā)送的文本,點擊“發(fā)送”按鈕,另外一個程序的接收端就得到了以下的結果;說明程序的串口收發(fā)已經實現。我們還可以通過內部賦值的方式給發(fā)送端送出其他的數據,用此方法完成“計算機”-“串口”-“單片機”的上位機和下位機通信。如圖5所示。
本次實驗編程過程簡單,實現方便,粗略實現了PC機的串口編程通信,完成了串口的“串口號選擇”、“串口基本參數的設置”、“串口數據的收發(fā)”等基本功能,在此基礎之上可以修改適應用戶的不同需求,從而實現“計算機”-“串口”-“單片機”的一些常用通信。適合一些“上位機”-“下位機”架構的自動化儀器儀表設備推廣應用。