QSerialPort 手动 RTS 开/关未同步呼叫

QSerialPort manual RTS on/off not synched to call

本文关键字:同步 呼叫 手动 RTS QSerialPort      更新时间:2023-10-16

我正在尝试通过串行端口发送到数据。对于控制流,我需要手动设置和清除 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 本机串行端口函数来设置/清除 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系统兼容。

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

所以代码现在看起来像

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

现在打开的 RTS 和关闭的 RTS 会在应该"发送"的时候"发送"。