我正在尝试使用QSerialPort来实现简单串行通信协议(protocol)的一侧。协议(protocol)接收端的板不在我的控制之下,因此我试图通过使用一根DE-9空电缆在同一板上从一个串行端口环回另一个端口来调试我的一侧,并运行一种简单的方法。依赖于相同的基础传输协议(protocol)代码的“侦听器”应用程序。
传输协议(protocol)要求在收到有效消息包后立即发送“确认”包,因此端口始终以读/写模式打开,并且在发送每个消息包之后,代码将等待并侦听确认。直到经过超时时间后,端 Eloquent 会再次关闭。 编辑4:但是,当程序不尝试发送消息或专门侦听数据时,该端口关闭。
我发现,代码的运行方式会有所不同,具体取决于运行Qt程序之前端口的波特率是否与Qt程序选择的波特率匹配。也就是说,我正在使用setBaudRate()
(在发送方和侦听方中)确定波特率,如果我将其设置为运行程序之前的波特率,则侦听方会看到正确的字节序列,但是如果设置将其发送给其他对象,然后侦听器只会在串行端口上看到垃圾。
(即使侦听器看到了正确的字节序列并发送了ack,其他程序也看不到这些ack,而且我也不知道为什么;我怀疑这个问题可能是相关的,但是这个问题并不是我的重点。)
实际使用什么波特率似乎无关紧要。即使Qt程序明确设置了波特率,我也只需要在运行Qt程序之前使用stty
对其进行设置。如果我使用stty
将波特率设置为Qt程序使用的波特率以外的其他值,则侦听器会看到垃圾。
设置波特率后,我已经为每个端口打印了baudRate(Input)
,baudRate(Output)
,dataBits()
,flowControl()
,parity()
和stopBits()
的值,以便评估波特率设置是否正确或串行端口的其他属性是否正确错误,但是在每种情况下打印的值都相同。
我已经尝试了stty
的其他属性(尽管没有进行广泛的尝试)(例如,在运行程序之前将两个端口都设置为raw
或cooked
),并且观察到,除了波特率之外,没有其他设置似乎有任何影响。
是否有人知道这里可能发生什么情况,如何对其进行调试,以及QSerialPort或QSerialPortInfo是否提供适当的工具来解决出现的任何不一致情况?
编辑:为了明确起见,我知道Qt波特率设置代码正在起作用,因为该协议(protocol)的远程端(不受我控制的那个)使用57600波特,并且我可以发送和接收一些使用Qt(不是stty
)将端口的波特率从默认的9600更改为57600后,带有该硬件的消息。(如果不更改波特率,则无法进行通信;我得到的字符与硬件不匹配实际上正在发送。)
还应该清楚的是,如果在我的程序中设置波特率没有任何影响,则环回测试将始终有效,因此Qt代码会产生一定的影响。
编辑2:设置波特率之前,Qt显然将baudRate()
所确定的速率感知为9600(默认速率),而不论stty
如何设置它。
另外,如果我使用stty
将“发送”端设置为“正确”波特率,将“侦听”端设置为“错误”波特率,则当两个端口都设置为时,我会得到部分正确的行为。提前“错误”的速率(即,侦听器看到消息,但是发送者从不看到确认)。
编辑3:我以前进行过编辑,注意到其中一些测试是在环回电缆拔掉的情况下完成的,但我刚刚意识到自己弄错了。
Qt版本: 5.4.0
操作系统: Debian 7
最佳答案
事实证明,由于我正在打开和关闭端口,因此丢失了数据。当QSerialPort
关闭时,数据要么没有首先被缓冲(由驱动程序缓冲),要么在端口重新打开后立即被丢弃。
大概,使用stty
设置波特率以匹配Qt
使用的波特率的原因影响了程序行为,原因是,当波特率已经是Qt
需要设置的波特率时,setBaudRate()
调用是空操作,并且关闭时无需采取任何清除操作即可恢复旧的波特率;而Qt
确实需要更改波特率时,在关闭端口时还必须恢复旧的波特率,这会占用大量的处理时间。