2014-01-27 137 views
0

我正在使用QT連接到硬件串行設備,我基於我的應用程序大致圍繞終端示例,但由於通信需要非常同步,因此串行處理程序生活在另一個線程。該連接通過一個2xRS232連接到帶有FTDI芯片組的USB適配器。關閉串口的正確方法QT

串行通信很好,我可以連接,發送命令等。但是,當我退出並重新加載應用程序時,串行端口似乎被阻止。

讓COM1爲連接的設備,COM2未連接。

如果我運行該程序,做一些與硬件通話並退出,下一次運行程序(數據LED不會在適配器上閃爍)時不能再連接到COM1,除非我嘗試首先連接到COM2。一旦我嘗試過,我可以像往常一樣連接回COM1。在硬件的參考實用程序中沒有看到這種行爲,因此必須以某種方式處理端口。

我身邊的代碼是:

void mydevice::closeSerialPort() 
{ 
    this->stop(); 
    serial->close(); 
    emit serialClosed(); 
    emit log("Serial port closed."); 
} 

serialQTSerialPort。首先發送一個停止命令來關閉硬件(與問題無關,這只是一種方便),然後我發送一個關閉命令給串口。

我有我的主窗口中的子類的QWidget,要求退出該命令:

/* In the constructor */ 
connect(this, SIGNAL(WindowClosed()), mydevice, SLOT(closeSerialPort())); 


void mainwindow::closeEvent(QCloseEvent *event) 
{ 
     emit WindowClosed(); 
     event->accept(); 
} 

沒有任何理由爲這種行爲?我假設我以某種方式阻止港口開放,但肯定會抱怨它已經開放。

另一個奇怪的問題是,說設備是在COM1上,我在我的應用程序中打開它,COM1在其他實用程序中無響應,設備出現在COM2上。但是,當我切換回我的程序並撥弄一下時,設備再次出現在COM1上(儘管總是在另一個應用程序的COM2中)。

回答

1

所以似乎有一個相當簡單的解決方案,但我不明白究竟是什麼導致了問題。

我有兩個線程,每個線程控制不同的串行設備。串行配置通過我從QT示例(終端)偷取的對話框訪問。每個線程都有一個此設置對話框的實例。看起來在選擇端口時出現了問題 - 例如,如果在調試器中選中,則對話框中的所有選擇實際上指向相同的COM端口。

無論如何,我把這寫成非線程安全的代碼,並將程序改爲只詢問串行端口名稱,因爲數據速率,停止位,奇偶校驗等由硬件固定,並且不會改變。這已經解決了這個問題。

0

有兩個可能的答案,我想:

  1. 過程不,儘管你關閉主窗口的終止。您如何驗證該流程實際上已被終止?

  2. 您對qt的serialport模塊的使用暴露了FTDI驅動程序中的一個錯誤。這並不是不可想象的,但我現在稱之爲遙遠的可能性。

就我個人而言,我沒有看到FTDI驅動程序的串口仿真的任何用途,它沒有任何理由添加額外的圖層。如果您不想使用諸如libftdi之類的東西,D2XX接口是實現它的方法。在Windows上,我發現D2XX和libftdi是唯一可行的替代方案,在虛擬機上,libftdi比D2XX工作得更好。

+0

我使用的是通用QT庫,因爲代碼很可能以各種系統結束,其中一些內置串行端口(舊套件!),其中一些可能使用Prolific驅動程序等。 我玩了更多,甚至只有在需要的波特率工程未使用的端口嘗試。例如該設備工作在115200波特。如果我嘗試使用9600打開COM2,然後在115200打開COM1,請使用zip。如果我嘗試COM2與115200,然後COM1,它的工作原理。 程序肯定被終止,QT Creator獲取程序的返回碼,任何東西都不會出現在taskmgr中。 – Josh

0

不知道這可能是有用的。

我有一個類似的問題(但不是相同的)與多產pl2303。 在我的情況下,當我關閉端口(或者甚至在啓動之前,在打開它之前!),無論如何都會收到數據,並在我打開端口時立即顯示。

這種情況只發生在usb-rs232適配器上,如果我使用ttyS0(物理串行端口),則不會出現問題。

對於我來說,解決方案是迫使QSerialPort :: clear()在QSerialPort :: open()之後清除緩衝區。這避免了準備好的信號被髮射並因此接收不需要的數據。