正确关闭串口QT的方法

时间:2014-01-27 01:20:55

标签: windows qt serial-port ftdi

我正在使用QT连接到硬件串行设备,我的应用程序大致围绕终端示例,但由于通信需要非常同步,因此串行处理程序存在于另一个线程中。连接是通过带有FTDI芯片组的2xRS232到USB适配器。

串口通讯很好,我可以连接,发送命令等。但是,当我退出并重新加载应用程序时,串口似乎被阻止了。

让COM1成为连接设备,COM2未连接。

如果我运行程序,与硬件进行一些对话并退出,下次运行程序时我不能再连接到COM1(数据LED不会在适配器上闪烁),除非我尝试首先连接到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中)。

3 个答案:

答案 0 :(得分:1)

所以似乎有一个相当简单的解决方案,但我不明白究竟是什么导致了这个问题。

我有两个线程,每个线程控制一个不同的串行设备。通过我从QT示例(终端)窃取的对话框访问串行配置。每个线程都有一个此设置对话框的实例。选择端口时似乎出现了问题 - 例如,如果在调试器中检查,对话框中的所有选择实际上都指向相同的COM端口。

无论如何,我把它归结为非线程安全的代码,并将程序更改为只询问串口名称,因为数据速率,停止位,奇偶校验等都是由硬件修复的,并且不会更改。这解决了这个问题。

答案 1 :(得分:0)

我认为有两种可能的答案:

  1. 尽管您关闭了主窗口,但您的进程并未终止。您如何确认该流程实际上已被终止?

  2. 您使用qt的serialport模块会暴露FTDI驱动程序中的错误。这不是不可想象的,但我现在称之为遥远的可能性。

  3. 我个人认为FTDI驱动程序的串口仿真没有任何用处,它没有充分的理由添加额外的层。如果您不想使用libftdi之类的东西,可以使用D2XX界面。在Windows上,我发现D2XX和libftdi是唯一可行的替代品,libftdi在虚拟机上的运行效果要比D2XX好得多。

答案 2 :(得分:0)

不知道这是否有用。

我有一个类似的问题(但不一样)与多产的pl2303。 在我的情况下,当我关闭端口(或甚至在启动时,打开它之前!),无论如何都会以某种方式接收数据并在我打开端口时立即显示。

仅在使用usb-rs232适配器时才会发生这种情况,如果我使用ttyS0(物理串口),则不会出现问题。

我的解决方案是强制QSerialPort :: clear()在QSerialPort :: open()之后清除缓冲区。这样可以避免发出信号readyRead,从而避免接收不需要的数据。