Ⅰ QT串口編程 - 阻塞主機示例(Blocking Master)
Blocking Master 展示了如何在工作線程中使好正用QSerialPort的同步(synchronous)API為串列介面創建應用程序。
MasterThread是一個QThread子類,提供用於調度對從屬伺服器的請求的API。 此類提供了用於響應和報告錯誤的信號。 可以調用 transaction() 方法以使用所需的槐岩請求啟動新的主事務。 結果由 response() 信號提供。 如果出現任何問題,將發出 error() 或 timeout() 信號。
注意, transaction() 方法是在主線程中調用的,而請求是在MasterThread線程中提供的。 MasterThread數據成員在不同的線程中並發讀取和寫入,因此 QMutex 類用於同步訪問。
transaction() 方法存儲串列埠名稱,超時和請求數據。 可以使用 QMutexLocker 鎖定互斥鎖以保護此數據。 線程可以啟動,除非它已經在運行。 稍後將討論 wakeOne() 方法。
在 run() 函數中,首先是鎖定 QMutex 對象,然後使用成員數據獲取串列埠名稱,超時和請求數據。 完成此操作後,將釋放 QMutex 鎖。
在任何情況下都不應在獲取數據的過程中同時調用 transaction() 方法。 注意,雖然QString類是可重入的,但它不是線程安全的。 因此,建議不要在請求線程中讀取串列埠名稱,而在另一個線程中超時或請求數據。 MasterThread類一次只能處理一個請求。
在進入循環之前,將在 run() 方法中的堆棧上構造 QSerialPort 對象:
這樣就可以在運行循環時創建對象。 這也意味著所有對象方法都在 run() 方法的范圍內執行。
在循環內部檢查當前事務的串列埠名稱是否已更改。 如果已更改,則重新打開串列埠,然後重新配置。
循環將繼續請求數據,寫入串列埠並等待,直到所有數據都被傳輸為止。
警告:至於阻塞傳輸,應在每次write方法調用之後使用 waitForBytesWritten() 方法。 這將處理所有I / O常式,而不是Qt事件循環。
如果傳輸數據時發生超時錯誤,則發出 timeout() 信號。
成功請求後,有一個等待期的響應,然後再次讀取。
警告:至於阻塞替代方法,應在每次 read() 調用之前使用 waitForReadyRead() 方法。 這將處理鉛襪御所有I / O常式,而不是Qt事件循環。
如果接收數據時發生超時錯誤,則發出timeout()信號。
成功完成事務後,response()信號包含從從應用程序接收的數據:
之後,線程進入睡眠狀態,直到出現下一個事務。 線程在使用成員喚醒後讀取新數據,並從頭開始運行循環。
Ⅱ QT開發(五十)——QT串口編程基礎
一、QtSerialPort簡介
1、串口通信基礎
目前使用最廣泛的串口為DB9介面,適用於較近距離的通信。一般小於10米。DB9介面有9個針腳。
串口通信的主要參數如下:
A、波特率:衡量通信速度的參數,表示每秒鍾傳送的bit的個數。例如9600波特表示每秒鍾發送9600個bit。
B、數據位:衡量通信中實際數據位的參數,當計算機發送一個信息包,實際包含的有效數據位個數。
C、停止位:用於表示單個包的最後一位。典型的值為1和2位。
D、奇偶校驗位:串口通信中一種檢錯方式。常用的檢錯方式有:偶、奇校驗。
2、QtSerialPort模塊簡介
QtSerialPort模塊是QT5中附加模塊的一個模塊,為硬體和虛擬的串口提供統一的介面。
串口由於其簡單和可靠,目前在像嵌入式系統、機器人等工業中依舊用得很多。使用QtSerialPort模塊,開發者可以大大縮短開發串口相關的應用程的周期。
Qt SerialPort提供了基本的功能,包括配置、I/O操作、獲取和設置RS-232引腳的信號。
Qt SerialPort模塊暫不支持以下特性:
A、終端的特性,例如回顯,控制CR/LF等等
B、文本模式段飢
C、讀或寫操作的超時和延時配置
D、當RS-232引腳信號變化通知
#include <QtSerialPort/QtSerialPort>
要鏈接QtSerialPort模塊,需要在.pro文件中添加如下內容:
QT += serialport
二、QSerialPort
1、QSerialPort簡介仔賀
QSerialPort提供了訪問串口的介面函數。使用輔助類QSerialPortInfo可以獲取可用的串口信息。將QSerialPortInfo輔助類對象做為參數,使用setPort()或setPortName()函數可以設置要訪問的串口設備。
設置好埠後,可以使用open()函數以只讀、只寫或讀寫的模式打開使用。
注意,串口使用獨占方式打開。
使用close()函數關閉串口並且取消IO操作。
串口成功打開後,QSerialPort會嘗試確定串握戚返口的當前配置並初始化。可以使用setBaudRate()、setDataBits()、setParity()、setStopBits()和setFlowControl()函數重新配置埠設置。
有一對名為QSerialPort::dataTerminalReady、QSerialPort::requestToSend的屬性
QSerialPort提供了中止正在調用線程直到信號觸發的一系列函數。這些函數用於阻塞串口。
waitForReadyRead():阻塞調用,直到有新的數據可讀
waitForBytesWritten():阻塞調用,直到數據以及寫入串口
阻塞串口編程與非阻塞串口編程完全不同。阻塞串口不會要求時間循環並且通常會簡化代碼。然而,在GUI程序中,為了避免凍結用戶界面,阻塞串口編程只能用於非GUI線程。
QSerialPort也能使用QTextStream和QDataStream的流操作符。在試圖使用流操作符>>讀時,需要確保有足夠可用的數據。
2、QSerialPort成員函數
QSerialPort::QSerialPort(QObject *parent = Q_NULLPTR)
QSerialPort::QSerialPort(const QString &name, QObject *parent = Q_NULLPTR)
QSerialPort::QSerialPort(const QSerialPortInfo &serialPortInfo, QObject *parent = Q_NULLPTR)
[virtual] bool QSerialPort::atEnd() const
[signal] void QSerialPort::baudRateChanged(qint32 baudRate, QSerialPort::Directions directions)
[virtual] qint64 QSerialPort::bytesAvailable() const
[virtual] qint64 QSerialPort::bytesToWrite() const
[virtual] void QSerialPort::close()
void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo)
void QSerialPort::setPortName(const QString &name)
三、QSerialPortInfo
1、QSerialPortInfo簡介
QSerialPortInfo類提供已有串口設備的信息。使用QSerialPortInfo類的靜態成員函數生成QSerialPortInfo對象的鏈表。鏈表中的每個QSerialPortInfo對象代表一個串口,每個串口可以使用埠名、系統定位、描述、製造商查詢。QSerialPortInfo類對象也可以用做QSerialPort類的setPort()成員函數的參數。
2、QSerialPortInfo成員函數
QSerialPortInfo::QSerialPortInfo(const QSerialPort &port)
QSerialPortInfo::QSerialPortInfo(const QString &name)
QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other)
[static] QList<QSerialPortInfo> QSerialPortInfo::availablePorts()
QString QSerialPortInfo::description() const
bool QSerialPortInfo::hasProctIdentifier() const
bool QSerialPortInfo::hasVendorIdentifier() const
bool QSerialPortInfo::isBusy() const
QString QSerialPortInfo::manufacturer() const
QString QSerialPortInfo::portName() const
quint16 QSerialPortInfo::proctIdentifier() const
QString QSerialPortInfo::serialNumber() const
[static] QList<qint32> QSerialPortInfo::standardBaudRates()
void QSerialPortInfo::swap(QSerialPortInfo &other)
QString QSerialPortInfo::systemLocation() const
quint16 QSerialPortInfo::vendorIdentifier() const
3、QSerialPortInfo顯示串口信息實例
Ⅲ 我在Qt里寫一個向串口寫數據的程序,但是提示QIODevice::write: device not open,不知道怎麼解決!
是伺服器的埠沒有打開。
1、首先pro文件配置:Qt網路功能需要在pro文件增加網路庫。
注意事項:
int main()
{
Py_Initialize(); // 初始化// 將Python工作路徑切換到待調用模塊所在目錄,一定要保證路徑名的正確性string chdir_cmd = string("sys.path.append('/xxxxxxx/')");
// 載入模塊PyObject* moleName = PyString_FromString("xx"); //模塊名,不是文件名PyObject* pMole = PyImport_Import(moleName);
// 載入函數PyObject* pv = PyObject_GetAttrString(pMole, "xxx");// 調用函數PyObject* pRet = PyObject_CallObject(pv, xxx);
Ⅳ 用QT編寫一個串口通信的程序。為什麼標題為中文的時候顯示是亂碼,標題為英文則是對的。
中文編碼問題,在主函數加入:
QTextCodec *codec = QTextCodec::codecForName("System"); //獲取系統編碼
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
肯定就ok啦
Ⅳ 在QT下的串口編程
沖突了而已伍蔽,close調用的是mainwindow繼承的關閉槽而不是你串口的關閉,你可以腔明州試著加上::域訪槐渣問操作符試試。
Ⅵ 如何在QT中讀取串口數據
一、文件下載
文件下載地址:
也可以下載我上傳到網盤上的:
二、文件內容介紹
1.下載到的文件為qextserialport-1.2win-alpha ,解壓並打開後其內容如下。
(點擊圖片可以查看清晰大圖)
下面分別介紹:
(1)doc文件夾中的文件內容是QextSerialPort類和QextBaseType的簡單的說明,我們可以使用記事本程序將它們打開。
(2)examples文件夾中是幾個例子程序,可以看一下它的源碼,不過想運行它們好像會出很多問題啊。
(3)html文件夾中是QextSerialPort類的使用文檔。
(4)然後就是剩下的幾個文件了。其中qextserialenumerator.cpp及qextserialenumerator.h文件中定
義的QextSerialEnumerator類是用來獲取平台上可用的串口信息的。不過,這個類好像並不怎麼好用,而且它不是我們關注的重點,所以下面
就不再介紹它了。
(5)qextserialbase.cpp和qextserialbase.h文件定義了一個QextSerialBase
類,win_qextserialport.cpp和win_qextserialport.h文件定義了一個Win_QextSerialPort
類,posix_qextserialport.cpp和posix_qextserialport.h文件定義了一個
Posix_QextSerialPort類,qextserialport.cpp和qextserialport.h文件定義了一個
QextSerialPort類。這個QextSerialPort類就是我們上面所說的那個,它是所有這些類的子類,是最高的抽象,它屏蔽了平台特徵,
使得在任何平台上都可以使用它。
2.幾個類的簡單介紹。
下面是這幾個類的關系圖。
可以看到它們都繼承自QIODevice類,所以該類的一些函數我們也可以直接來使用。圖中還有一個QextBaseType類,其實它只是一個標
識,沒有具體的內容,它用來表示Win_QextSerialPort或Posix_QextSerialPort
中的一個類,因為在QextSerialPort類中使用了條件編譯,所以QextSerialPort類既可以繼承自
Win_QextSerialPort類,也可以繼承自Posix_QextSerialPort類,所以使用了QextBaseType來表示。這一點
我們可以在qextserialport.h文件中看到。再說QextSerialPort類,其實它只是為了方便程序的跨平台編譯,使用它可以在不同的
平台上,根據不同的條件編譯繼承不同的類。所以它只是一個抽象,提供了幾個構造函數而已,並沒有具體的內容。在qextserialport.h文件中的
條件編譯內容如下:
#ifdef_TTY_POSIX_
#include「posix_qextserialport.h」
#define QextBaseTypePosix_QextSerialPort
#else
#include「win_qextserialport.h」
#define QextBaseTypeWin_QextSerialPort
#endif
所以,其實我們沒有必要使用這個類,直接使用Win_QextSerialPort或Posix_QextSerialPort就可以了。當然如果
你想使用這個類,實現同樣的源程序可以直接在Windows和Linux下編譯運行,那麼一定要注意在Linux下這里需要添加
#define _TTY_POSIX_ 。而我們這里為了使得程序更明了,所以沒有使用該類,下面也就不再介紹它了。
QextSerialBase類繼承自QIODevice類,它提供了操作串口所必需的一些變數和函數等,而
Win_QextSerialPort和Posix_QextSerialPort均繼承自QextSerialBase
類,Win_QextSerialPort類添加了Windows平台下操作串口的一些功能,Posix_QextSerialPort類添加了
Linux平台下操作串口的一些功能。所以說,在Windows下我們使用Win_QextSerialPort類,在Linux下我們使用
Posix_QextSerialPort類。
3.在QextSerialBase類中還涉及到了一個枚舉變數QueryMode。
它有兩個值Polling和EventDriven
。QueryMode指的是讀取串口的方式,下面我們稱為查詢模式,我們將Polling稱為查詢方式Polling,將EventDriven稱為事件驅動方式。
事件驅動方式EventDriven就是使用事件處理串口的讀取,一旦有數據到來,就會發出readyRead()信號,我們可以關聯該信號來讀取串口的數據。在事件驅動的方式下,串口的讀寫是非同步的,調用讀寫函數會立即返回,它們不會凍結調用線程。
而查詢方式Polling則不同,讀寫函數是同步執行的,信號不能工作在這種模式下,而且有些功能也無法實現。但是這種模式下的開銷較小。我們需要自己建立定時器來讀取串口的數據。
在Windows下支持以上兩種模式,而在Linux下只支持Polling模式。
三、小結。
這里講了這么多,最後要說的只是,我們在Qt中使用這個類編寫串口程序,根據平台的不同只需要分別使用四個文件。
Ⅶ QT 串口編程收發數據時,怎麼樣才能不卡UI
你exec();怎麼放到線程裡面去運行?exec();界面應該都放到主線程
然後你要乾的活都放到線程的run函數里去處理。
線程里發送信號,分阻塞和非阻塞,在connect的第五個參數設置為QueuedConnection
可以了解一下sendMessage和postMessage的區別
Ⅷ 新手,有關於qt5串口編程
接收端是否適用串口調試軟體模擬, 是否已經連接成功, write返回值的是多少, 判斷有沒有收到的依據是有沒有字元顯示還是接收到的字元數量, 寫入的字元是否是可見字元, 寫入的字元如果是中文有沒有進行轉碼
Ⅸ QT下的串口編程我想從串口讀數據,但是讀第3次的時候程序自動崩潰了
str2 = list1.at(2)+","+list1.at(3)+","+list.at(4)//
我覺得問題可能在這 因為你每次讀到得數據時不一樣的 不能確保切割後都能分成4個 對list的越界訪問造成程序崩潰 你可以把buf的內容輸出看一下 看是不是能分割成四個!