【问题标题】:Correct way to close a serial port QT关闭串口QT的正确方法
【发布时间】:2014-01-27 01:20:54
【问题描述】:

我正在使用 QT 连接到硬件串行设备,我的应用程序大致基于终端示例,但由于通信需要非常同步,串行处理程序位于另一个线程中。通过 2xRS232 到带有 FTDI 芯片组的 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 中)。

【问题讨论】:

    标签: windows qt serial-port ftdi


    【解决方案1】:

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

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

    无论如何,我将其归结为非线程安全代码,并将程序更改为只询问串行端口名称,因为数据速率、停止位、奇偶校验等由硬件固定,不会改变。这已经解决了问题。

    【讨论】:

      【解决方案2】:

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

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

      2. 您对 qt 串行端口模块的使用暴露了 FTDI 驱动程序中的错误。这并非不可想象,但目前我认为这是一种遥远的可能性。

      我个人认为 FTDI 驱动程序的串行端口仿真没有任何用处,它无缘无故地添加了一个额外的层。如果您不想使用libftdi 之类的东西,则可以使用 D2XX 接口。在 Windows 上,我发现 D2XX 和 libftdi 是唯一可行的替代方案,libftdi 在虚拟机上的工作比 D2XX 好得多。

      【讨论】:

      • 我正在使用通用 QT 库,因为代码可能最终会出现在各种系统上,其中一些系统内置了串行端口(旧套件!),其中一些可能使用 Prolific 驱动程序等。我玩得更多,甚至更奇怪的是,仅以所需的波特率尝试未使用的端口即可。例如该设备工作在 115200 波特。如果我尝试用 9600 打开 COM2,然后在 115200 打开 COM1,请压缩。如果我用 115200 和 COM1 尝试 COM2,它可以工作。程序肯定终止了,QT Creator 得到程序的返回码,taskmgr 中什么也没有出现。
      【解决方案3】:

      不知道这是否有用。

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

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

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

      【讨论】:

        猜你喜欢
        • 2018-09-14
        • 2010-11-30
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多