0

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

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

设 COM1 为已连接设备,COM2 未连接。

如果我运行程序,与硬件进行一些对话并退出,我将无法在下次运行程序时连接到 COM1(适配器上的数据 LED 不闪烁),除非我尝试连接到 COM2第一的。一旦我尝试了这个,我就可以像往常一样连接回 COM1。这种行为在硬件的参考实用程序中看不到,因此必须归结为我处理端口的某种方式。

我的关闭代码是:

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

serial是一个QTSerialPort。首先发送停止命令以关闭硬件(与问题无关,这只是为了方便),然后我向串口发送关闭命令。

我的主窗口有一个子类 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 中)。

4

3 回答 3

1

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

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

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

于 2014-01-31T01:15:48.973 回答
0

有两个可能的答案,我认为:

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

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

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

于 2014-01-27T07:30:46.917 回答
0

不知道这是否有用。

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

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

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

于 2015-05-02T10:44:26.597 回答