QSerialPort 手动 RTS on/off 未同步调用

QSerialPort manual RTS on/off not synched to call

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

我用的代码基本是

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

变量 package 是一个 QVector<int8_t> 但这与问题无关。上面的代码每五秒在计时器中调用一次。

问题是 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 开启在我发送消息时正确发生,但 RTS 关闭直到我下次发送时才会发生。

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

我是否需要连接到特殊信号才能知道何时可以调用 setRequestToSend 来关闭 RTS?我是否需要使用 Windows 本机串行端口功能来 set/clear 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 on/off。它使用 RS232 到 RS485 转换器(内部制造)与 Modbus 设备通信。旧程序可以毫无问题地设置和清除 RTS,但我使用 QSerialPort 的替换程序却不行。我想避免获取 RTS 问题的本机 Windows 句柄,但除非有任何其他解决方案,否则我会这样做。

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

事实证明,直到程序 returns 到事件循环中,数据才真正写入(包括 RTS 关闭标志)。 如果waitForBytesWritten函数被调用。

所以代码现在看起来像

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

RTS 打开和关闭现在是 "sent" 他们应该的时候。