1

我正在尝试通过 USB 串行电缆将微控制器与我的台式 PC 连接。我台式电脑的操作系统是 Windows 8.1,USB 串口线是 TTL-232R-3V3。(FTDI)(Qt 版本:5.2.0 beta1,QtCreator 版本:3.0,编译器:MSVC2012)

现在我正在尝试读/写环回测试,这就是 USB 串行电缆的 RX/TX 引脚相互连接的原因。

这是我的代码。

#include <QtCore/QCoreApplication>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QtCore/QDebug>

#define PORT_NAME "COM3"
#define BAUDRATE 19600
#define TIMEOUT_MS 1000

QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QSerialPort pSerial(PORT_NAME);
    const char strMsg[] = "#1:Send data line \n #2:Send data line\n #3:Send data line end\n";
    char strBuf[256];
    qint64 nByte;


    if(pSerial.open(QIODevice::ReadWrite)){
        pSerial.setBaudRate(BAUDRATE);
        qDebug() << "OPEN PASS";

        pSerial.write(strMsg);
        pSerial.flush();
        if(pSerial.waitForBytesWritten(TIMEOUT_MS)){
            qDebug() << "WRITE PASS";
        }


        pSerial.waitForReadyRead(TIMEOUT_MS);
        while(true){
            if( pSerial.canReadLine()){
                qDebug() << "CAN READ LINE";
                nByte = pSerial.readLine(strBuf,sizeof(strBuf));
                qDebug() << "Length: " << nByte;
                qDebug() << "Read data: " << strBuf;

            }
        }
        pSerial.close();
    } else {
        qDebug() << "OPEN FAIL\n";
    }
    return a.exec();
}

当程序开始运行时,结果与我预期的不同。只能接收发送数据的第一行。因此,“读取数据:#1 发送数据行”打印在控制台上。但是将永远不会收到其余发送的数据。有谁知道为什么?

任何帮助,将不胜感激。提前致谢。

编辑:我根据 Papp 的评论修改了我的代码。然后它按我的预期工作。已收到所有发送的消息。

这是否意味着我误解了 readLine() 或 canReadLine() 的用法?

//        while(true){
//            if( pSerial.canReadLine()){
//                qDebug() << "CAN READ LINE";
//                nByte = pSerial.readLine(strBuf,sizeof(strBuf));
//                qDebug() << "Length: " << nByte;
//                qDebug() << "Read data: " << strBuf;
//            }
//        }

        pSerial.waitForReadyRead(TIMEOUT_MS);
        QByteArray readData = pSerial.readAll();
        while (pSerial.waitForReadyRead(TIMEOUT_MS)) {
            readData.append(pSerial.readAll());
        }
        qDebug() << "Read data: " << readData;

第二次编辑:以下代码也适用于我。

while(true){
    if( pSerial.waitForReadyRead(TIMEOUT_MS) && pSerial.canReadLine()){ // I revised this line
        qDebug() << "CAN READ LINE";
        nByte = pSerial.readLine(strBuf,sizeof(strBuf));
        qDebug() << "Length: " << nByte;
        qDebug() << "Read data: " << strBuf;
        qDebug() << "Error Message: " << pSerial.errorString();

    }
}
4

2 回答 2

1

那是因为您需要像这样循环读取:

QByteArray readData = serialPort.readAll();
while (serialPort.waitForReadyRead(5000))
    readData.append(serialPort.readAll());

creadersync有关我添加到 5.2 的详细信息,请参阅示例。您还可以检查creaderasync非阻塞操作的示例。

公平地说,我们还没有对 readLine 进行太多测试,但它在 Unix 上对我有用,在 Windows 上也适用于其他人。

于 2013-12-15T11:37:00.163 回答
0

您犯的错误是期望在waitForReadyRead返回时收到所有发送的数据。完成waitForReadyRead后,您只能保证有一些数据可供读取。它可能只有一个字符,不一定是一整行。

您上次修改的循环是几乎正确的方法。您应该在单独的循环中嵌套读取行。以下代码是它应该如何完成的,并且符合 的语义QIODevice

while (pSerial.waitForReadyRead(TIMEOUT_MS)) {
  while (pSerial.canReadLine()) {
    qDebug() << "NEW LINE";
    QByteArray line = pSerial.readLine();
    qDebug() << "Length: " << line.size();
    qDebug() << "Read data: " << line;
    qDebug() << "Error Message: " << pSerial.errorString();
  }
}
qDebug << "TIMED OUT";

请注意,这些代码甚至都不应该在 GUI 线程中运行。理想情况下,您应该将其移动到 QObject,使用QIODevice(因此QSerialPort)发出的信号,并将该对象移动到单独的线程。

GUI 线程有时会长时间阻塞,通常不希望它干扰设备通信的及时性。同样,您不希望设备超时阻塞 GUI 线程。两者都同样糟糕,并且是糟糕用户体验的常见来源。Qt 使多线程变得非常容易——为了您的用户而利用它,并正确地使用它。

于 2013-12-17T18:56:46.170 回答