我正在尝试通过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();
}
}
答案 0 :(得分:1)
那是因为你需要读一个这样的循环:
QByteArray readData = serialPort.readAll();
while (serialPort.waitForReadyRead(5000))
readData.append(serialPort.readAll());
请参阅creadersync
示例,了解我添加到5.2的详细信息。您还可以查看creaderasync
示例以了解非阻止操作。
公平地说,我们没有对readLine进行过那么多测试,但它在Unix上适用于我,在Windows上也适用于其他人。
答案 1 :(得分: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使多线程变得非常容易 - 为用户利用它,并正确地进行。