Linux讀取串口資料__Linux

來源:互聯網
上載者:User
一、前言

    最近項目中需要在Linux系統下讀取串口資料,由於使用的Ubantu系統,開發工具是Qt Creator,所以首先在網上百度了一下,找到了幾篇部落格,大致內容上都差不多。由於使用的Qt4,其沒有內建的串口類(Qt5就內建了串口類了,可以直接使用),Qt的強大就在於它的開源性和跨平台型,針對Qt4在Linux下的串口程式,網上有一個第三方庫,即qextseriaport類,單大多數博友寫的關於qextseriaport類的使用都是針對Windows平台的,既然Qt是跨平台的,那麼qextseriaport也肯定是支援Linux平台的,在網上找了一下,找到一個針對Linux系統下應用qextseriaport的博文,基於linux (fedora 17)的QT串口通訊執行個體,本文主要是針對這篇文章,根據在實驗過程中出現的一些問題的總結,進一步詳細說明在Linux系統下使用qextseriaport類,進行串口資料讀取。


二、問題背景

    大致為:有一個發送端周期性的往本機串口上發送資料,本機需要定時讀取串口資料,解析,擷取自己想要的資訊。實際描述為:由於是做智能駕駛的,需要讀取車輛速度,通過OBD裝置讀取並解析車輛速度,然後通過藍芽發送給PC串口(也是通過一個藍芽模組接收),PC端串口定時接收串口資料並解析。

    在上述過程中,有一個問題需要注意:發送方是周期性的不停的發送資料,也就是說PC機串口一直有資料進來,最常見的是發送端頻率比接收端頻率高,即準備讀取串口資料時總可以讀取的資料,但也也導致了另一個問題,那就是怎麼處理接收端串口緩衝,因為你每次的讀取操作都必須要把當前串口緩衝區中資料全部讀取出來,不能唯讀一部分,不然發送端一直有資料進來,而你每次都不讀玩,就會造成緩衝區溢位。


三、串口的實質是什麼

    但凡接觸過Linux系統知識或者瞭解電腦系統原理,那你一定通過一句話“在任何作業系統下,一切都是檔案”,Linux系統就是這句話的最完美的實現,即在Linux系統下,你完全可以把所有東西當成是一個檔案、即所有東西都可以按照“開啟——設定——讀寫——關閉”的模式進行,同樣,在Linux下串口也可以看成是一種檔案(其實任何作業系統下都可以這樣認為),你要讀寫串口資料,就必須先開啟、設定串口,然後讀寫,讀寫完畢,就必須要關閉串口。


四、Ubantu下Qt 串口資料讀取程式

    首先,你可以先瀏覽一下基於linux (fedora 17)的QT串口通訊執行個體,知道一個大致的流程,並按照要求下載qextseriaport源碼,將相應檔案拷貝到自己的工程目錄下,就可以按照他說的編寫代碼了,其實他這個只是一個簡單的demo,可以自己寫一個稍微複雜一點的。

    看了他的代碼之後,可能你已經大致明白了,他的操作流程完全是按照“開啟——設定——讀寫——關閉”的操作模式來操作串口的,其“開啟和設定”過程都是在MainWindow的建構函式裡面進行的,“讀取”操作其實就是一個函數readAll(),為了實現定時讀取,需要與一個QTimer connect,其實你完全可以不用定時器(在他的說明裡面說的是必須要用定時器)定時器的功能是什麼。不就是定時觸發其所關聯的函數嗎。其實質是你要定期調用readAll()函數,你完全可以自己控制這個定時操作,即可以在你的主函數裡面周期性調用readAll()函數就行了,最常見的,如果你要一直度,就在while(1)迴圈裡面調用readAll()函數,“關閉”操作是在MainWindow的解構函式裡面調用的。

    由於我的Qt工程比較大,不是只有一兩個編譯模組,所以我是自己調用的readAll()函數,並沒有與QTimer進行關聯,因為我有一個主控程式(其實也就是mian函數啊),所以就在主控程式裡面調用的readAll()函數,實現周期性的讀取串口資料,我的讀取車輛速度檔案如下:

ReadCarSpeed.h

#ifndef READCARSPEED_H#define READCARSPEED_Hvoid OpenCom();   //開啟、設定串口void ReadSpeed();     //讀取、解析資料,關閉操作也是在退出介面時調用#endif // READCARSPEED_H
ReadCarSpeed.cpp

#include "ReadCarSpeed.h"#include "posix_qextserialport.h"extern int carSpeed;Posix_QextSerialPort *myCom;void OpenCom(){    //定義串口對象,並傳遞參數,在建構函式裡對其進行初始化    myCom = new Posix_QextSerialPort("/dev/ttyUSB1",QextSerialBase::Polling);    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(50);     //延時設定,設定為延時20ms}void ReadSpeed(){    QByteArray temp = myCom->readAll();     //讀取串口緩衝區的所有資料給臨時變數temp    //把臨時變數temp轉換成整型變數carSpeed    QByteArray c = "KM/H";      //發送端發送的資料為“NKM/H”,其中N表示實際車速,由於發送端頻率比接收端頻率快,所以每次調用readAll()讀取的資料中是多個連續的“NKM/H”字串,形如“NKM/HNKM/HNKM/HNKM/HNKM/HNKM/HNKM/H”//由於我需要的是最新的車輛速度,所以只需要當前讀取字串中最後一個速度字元子串,使用QByteArray的成員函數lastIndexOf就可以實現,其傳回值是最後一個KM/H的位置,這屬於C++字串搜尋知識點//博友可以自行翻閱C++Primer(第五版P325)    int index = temp.lastIndexOf(c);     //返回最後一個c匹配位置    QByteArray speedstr = temp.mid(index-1,1);     //擷取速度資訊    carSpeed = speedstr.toInt();    //轉換為整型,賦值給全域變數carSpeed(是一個全域變數)}
(1)開啟串口:

    在ReadCarSpeed.cpp檔案中,OpenCom()函數負責開啟和設定串口,這裡有一點需要囉嗦一下:myCom->setTimeout(50);延時設定函數,我這裡設定的是50ms,對於這個延時,我的理解是本機串口的接收頻率,注意這個接收頻率是不同於你讀取的頻率的,這裡的接收頻率是本機串口緩衝區接收資料的延時,即沒50ms就有一個資料進去接收緩衝區隊列(要理解資料緩衝區實際就是一個隊列,先進先出),而你讀取的頻率是你調用readAll()函數的頻率,如我的讀取頻率就是主控程式的頻率(大約為500ms),所以每次大約讀取10個速度資訊。 (2)資料讀取與解析:

    ReadSpeed()函數中首先是調用readAll()函數讀取緩衝區中全部資料,然後解析資料,上面說過,每次讀取操作大約讀取了10個速度資訊(或者更多),而我需要的是最新的車速資訊,而緩衝區隊列中最新的車速資訊是隊列中的最後一個速度,所以只提取QByteArray中的最後一個速度,這通過C++的字元搜尋(匹配)實現,具體可以查閱C++Primer(第五版P325)。這裡QByteArray就是一個位元組數組,可以儲存任何資料,它的用法可以查看Qt Assistant文檔。

    總之,在我的應用程式中,首先是調用一次OpenCom函數,開啟並設定串口,然後周期性的調用ReadSpeed函數(其實質就是周期性的調用readAll函數)就能讀取最新的車速資訊。






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.