由於有關ARM開發板很多外設都是支援串口通訊的,所以在QT下編寫一個串口通訊程式就顯得尤為重要。下面將一步一步敘述開發過程:
Linux下QT串口通訊相關檔案及常式下載。。。
1、開發板上裝置驅動位置:/dev下存有各種裝置驅動檔案名稱
2、首先來看一下串口通訊幾個關鍵檔案: posix_qextserialport.cpp和posix_qextserialport.h檔案定義了一個 Posix_QextSerialPort類; qextserialbase.cpp和qextserialbase.h檔案定義了一個 QextSerialBase類 ; qextserialport.cpp和qextserialport.h檔案定義了一個QextSerialPort類 。
3、讀取串口方式:Polling(查詢方式)和EventDriven(事件驅動方式) 此兩種方式在QextSerialBase類的一個枚舉變數QueryMode中定義了。
事件驅動方式:使用事件處理串口的讀取,一旦有資料到來,就會發出readyRead()訊號,在事件驅動、的方式下,串口的讀寫是非同步,調用讀寫函數會立即返回,它們不會凍結調用線程。 查詢方式:讀寫函數是同步執行的,訊號不能工作在這種模式下,而且有些功能也無法實現。需要建立定時器來讀取串口的資料。
注意:在 Windows 下支援以上兩種模式,而在 Linux 下只支援 Polling 模式。
4、總結一下: 我們在Qt中使用這個類編寫串口程式,根據平台的不同只需要分別使用四個檔案。在Linux下是: qextserialbase.cpp和qextserialbase.h 以及posix_qextserialport.cpp和posix_qextserialport.h 在Linux下我們只能使用查詢Polling方式。
5、下面開始建立一個基本QT工程: 工程命名為myCom,Base Class選擇QWidget。
然後將有關Linux下串口設定檔(cpp和h檔案)添加到工程裡面去:
6、接下來修改下ui介面。如下圖:
7、widget.h檔案中進行對象及函式宣告 。 添加標頭檔包含: #include “posix_qextserialport.h”,然後在private中聲明對象:Posix_QextSerialPort *myCom; 聲明私人槽函數: private slots: void on_pushButton_clicked(); //”發送資料”按鈕槽函數 void readMyCom(); //讀取串口
8、widget.cpp在建構函式添加: myCom = new Posix_QextSerialPort("/dev/ttySAC3",QextSerialBase::Polling); myCom ->open(QIODevice::ReadWrite); //以讀寫方式開啟串口 myCom->setBaudRate(BAUD115200); //傳輸速率設定,我們設定為115200 myCom->setDataBits(DATA_8); //資料位元設定,我們設定為8位元據位 myCom->setParity(PAR_NONE); //同位設定,我們設定為無校正 myCom->setStopBits(STOP_1); //停止位設定,我們設定為1位停止位 myCom->setFlowControl(FLOW_OFF); //資料流控制設定,我們設定為無資料流控制 //myCom->setTimeout(10); 以上是對一個串口的初始化配置資訊。 程式寫到這裡試著編譯一下,解決一下出現的錯誤。
9、回顧一下:程式至此,已完成串口通訊的介面設計與串口初始化配置部分。 接下來思考一下:查詢方式(polling:輪詢)的原理。 通過建立一個定時器,定時“詢問”串口是否有資訊待讀取。如果有,系統留給串口一定時間來讀取,如果沒有,繼續“詢問”。 建立一個定時器: readTimer = new QTimer(this); readTimer->start(100); /*開啟定時器,並且每100ms後詢問一次串口。定時的時間一到,馬上產生timeout()訊號,繼續執行自訂槽函數readMyCom() */ connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));
10、 注意:串口初始化中值得注意的一點
myCom->setTimeout(10);
這裡的setTimeout()與定時器的timeout()區別: PC機向ARM通過串口發送資訊時,會有一個“中間儲存空間”----即串口緩衝區。setTimeout()作用是定時讀取資料到緩衝區,而timeout()則是定時讀取串口緩衝區內容。setTimeout(ms)裡面大小參數設定原則:越小越好,不過如果pc機一次性發送的資料比較龐大,應該增大參數大小。
11、經過上述講解,大家應該知道了串口通訊最核心的部分。下面將程式的兩個自訂槽函數補充完整。
void Widget::readMyCom() //讀取串口資料並顯示出來 { QByteArray temp = myCom->readAll(); //讀取串口緩衝區的所有資料給臨時變數temp ui->textBrowser->insertPlainText(temp); //將串口的資料顯示在視窗的文本瀏覽器中 } void Widget::on_pushButton_clicked() //發送資料 { myCom->write(ui->lineEdit->text().toAscii()); //以ASCII碼形式將資料寫入串口 }