QSerialPort 手动 RTS 开/关未与调用同步

Posted

技术标签:

【中文标题】QSerialPort 手动 RTS 开/关未与调用同步【英文标题】:QSerialPort manual RTS on/off not synched to call 【发布时间】:2019-09-03 08:40:07 【问题描述】:

我正在尝试通过串行端口发送数据。对于控制流,我需要手动设置和清除 RTS 行:在我发送数据时设置它(RTS on),并在我完成发送并准备好接收回复时清除它(RTS off)。

我使用的代码基本是

serialPort->setRequestToSend(false);
serialPort->write(reinterpret_cast<char*>(package.data()), package.size());
serialPort->flush();
serialPort->setRequestToSend(true);

变量packageQVector&lt;int8_t&gt;,但这与问题无关。上面的代码每五秒在一个定时器中调用一次。

问题是 RTS 关闭直到我下次发送消息时才会发生,当我需要它立即发生时。

查看以下嗅探日志:

10:11:06 +00:06.301   Set RTS: on
10:11:06 +00:06.302 < 0000  01 01 00 01 00 01 ac 0a                          ........
10:11:11 +00:11.300   Set RTS: off
10:11:11 +00:11.300   Set RTS: on
10:11:11 +00:11.301 < 0000  01 01 00 01 00 01 ac 0a                          ........
10:11:16 +00:16.300   Set RTS: off
10:11:16 +00:16.301   Set RTS: on
10:11:16 +00:16.301 < 0000  01 01 00 01 00 01 ac 0a                          ........

从日志中可以看出,RTS on 仅在我发送消息时正确发生,但 RTS 关闭直到我下次发送时才会发生。

flush 调用无关紧要,在 setRequestToSend(true) 之后添加另一个 flush 调用也无济于事。尝试阅读也无济于事。

我是否需要连接特殊信号才能知道何时可以致电setRequestToSend 来关闭 RTS?是否需要使用 Windows 原生串口功能来设置/清除 RTS?还是我只是做错了什么,或者对 setRequestToSend 函数和 QSerialPort 的工作方式或一般串行端口的工作方式有一些误解?

作为参考,下面是我配置串口的方法:

serialPort->setDataBits(QSerialPort::Data8);
serialPort->setBaudRate(QSerialPort::Baud115200);
serialPort->setParity(QSerialPort::NoParity);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setFlowControl(QSerialPort::NoFlowControl);

端口也打开了。


一点背景知识:我正在尝试替换一个已经过时的现有程序,并且在移植到 Windows 10(来自 Windows XP)时也遇到了问题。它使用本机 Windows 串行端口功能进行读写,以及手动处理 RTS 开/关。它使用 RS232 到 RS485 转换器(内部制造)与 Modbus 设备通信。旧程序可以毫无问题地设置和清除 RTS,但我使用 QSerialPort 的替换程序不能。我想避免为 RTS 问题获取本机 Windows 句柄,但除非有任何其他解决方案,否则我会这样做。

我在 32 位模式下使用 Qt 5.6.3 和 VisualC++ 2017 (14.16.27023),因为我希望该程序与仍在使用的旧 Windows XP 系统兼容。

【问题讨论】:

它是什么版本?他们说在 5.7.4(?)之前修复了一个错误,即如果启用了流控制,则 RTS 设置不正确。此外,我在混合嵌入式 ahrdware 和没有 RS 端口的笔记本电脑方面的工作表明,RTS 与 USB“虚拟”RS-232 有点问题。其他一些 RS 也可能有问题(422、485?)。这取决于它是哪种适配器,一些廉价的非法仿冒品(显然这是一项专利,拥有串行 USB 控制器!)确实存在实施问题, 在 Windows 上,您将难以准确打开和关闭 RTS,我从以前在 Windows 和 RS485 上使用 Modbus 协议的经验中知道这一点。最后,我们从 KK systems 购买了一个设备,它在检测到数据时会自动断言 RTS 线路。这是一个更好的解决方案。 Windows 在计时方面很差。 【参考方案1】:

在程序返回事件循环之前,数据实际上并没有被写入(包括 RTS 关闭标志)。 或者如果调用了waitForBytesWritten函数。

所以代码现在看起来像

serialPort->setRequestToSend(true);
serialPort->write(reinterpret_cast<char*>(package.data()), package.size());
serialPort->waitForBytesWritten(100);
serialPort->setRequestToSend(false);

RTS on 和 RTS off 现在会在应该的时候“发送”。

【讨论】:

以上是关于QSerialPort 手动 RTS 开/关未与调用同步的主要内容,如果未能解决你的问题,请参考以下文章

mac上的mxe交叉编译器QSerialPort

基于 RTS 超低延时直播优化强互动场景体验

上传到 Google Play 时,android apk 未与 zip 对齐

库未与 0.41 版本的 react-native 链接

如何在 QML 中注册 QSerialPort?

从另一个线程向 QSerialPort 发送数据