目标
在Qt应用程序中,我需要控制GPIO引脚,具体取决于通过串行总线发送的数据。因此,只要传输数据,就需要将其设置为HIGH,传输结束后立即将其设置为LOW。将其视为串行通信流控制引脚,当设置为1时,它将启用发送,而设置为0时,则将允许接收数据。整个系统是半双工的,并且以主从方式进行通信。
问题
我设法接近解决方案,即将任何传输之前将其设置为HIGH,根据波特率引入一定的延迟(我使用QThread:usleep()
),然后再次将其设置为低,但是当我用示波器进行可视化时,得到的是随机的脉冲“拉伸”(保持高电平的时间长于应有的时间)。
尝试的解决方案
好吧,似乎有些“魔术”正在发生,这除了我手动定义的延迟之外,还增加了一些额外的延迟。为了消除这种可能性,我使用了bytesWritten()
信号,因此当我们将实际数据写入端口时,可以触发setPinLow()
插槽。所以我的代码现在看起来像这样:
classTTY::classTTY(/*someStuff*/) : port(/*some other stuff*/)
{
s_port = new QSerialPort();
connect(s_port, SIGNAL(bytesWritten(qint64)), this, SLOT(setPinLow()));
if(GPIOPin->open(QFile::ReadWrite | QFile::Truncate | QFile::Text | QFile::Unbuffered)) {
qDebug() << "GPIO pin ready to switch.";
} else {
qDebug() << "Failed to access GPIO pin";
}
bool classTTY::sendData(data, replyLength)
{
directionPinEnable(true);
if(m_port->isOpen()) {
s_expectedReplyLength = replyLength;
s_receivedData.clear();
s_port->flush();
s_port->write(data);
return true;
}
return false;
}
void classTTY::setPinLow()
{
gpioPinEnable(false);
}
void classTTY::gpioPinEnable(bool enable){
if(enable == true){
GPIOPin->write("1");
} else if (enable == false) {
GPIOPin->write("0");
}
}
在实现它之后,该引脚开始真正发出短脉冲,更像是“尖峰”,这暗示着(我认为)现在只要Qt write()
持续,它就会一直保持高电平,而不是数据的实际传播持续进行。
问题
QThread::usleep
方法会导致脉冲展宽?答案 0 :(得分:0)
- 当我使用朴素的QThread :: usleep方法时,会导致脉搏延长的额外延迟是什么?
Linux不是实时操作系统,线程睡眠会在不小于指定时间的情况下暂停进程。在休眠期间,其他线程和进程可能会运行,并且可能不会在比您的休眠周期更长的时间内产生处理器,或者可能根本不产生并消耗它们分配给操作系统的整个时间片。除此之外,内核驱动程序中断处理程序将始终抢占用户级进程。 Linus有一个用于实时调度的构建选项,但是保证仍然不够可靠,以至于真正的实时操作系统和延迟通常会变差。
还要注意,不仅线程的挂起时间可以长于睡眠时间,而且传输的扩展量可能超过波特率的位数-内核驱动程序可以被其他驱动程序抢占并引入内部-您无法控制的字符间距。
- 为什么信号时隙方法是不起作用的,因为它是事件驱动的?
QSerialPort::waitForBytesWritten()
的文档说明:
此函数将阻塞,直到至少一个字节已写入串行端口并且已发出bytesWritten()信号为止。
因此很明显,其语义是“已写入 一些数据”,而不是“ 所有数据”已写”。每当写入字节时,它将返回,然后再次调用,如果继续写入字节,它将很可能立即返回(因为QSerialPort
被缓冲并且将独立于应用程序写入数据)。
- 一般来说,如何指示引脚在数据传输期间仅处于活动状态,然后再次下降到零,这样我才能收到从设备的答复?
不幸的是,Qt并不是答案。此行为需要在串行端口内核驱动程序中实现,或者至少在Qt的较低级别实现。 Qt QSerialPort
抽象不能为您提供控制或深入了解所需的“在线”实际发生情况的级别。从硬件上来说,它有些距离了-有充分的理由。
但是,有一个简单的解决方案-不用担心!似乎完全没有必要。这是主从通信,因此数据本身是 流控制。从属设备直到讲话后才开始说话,而主控器必须等待并等待答复。为什么奴隶除了说话所暗示的以外还需要其他任何说话的权限?