在使用qt编写串口助手时,想要做一个自动寻找串口的功能,因为项目所使用的开发板会返回从串口写入的数据,所以根据此特性,可以做一个自动寻找可用串口的功能。下面是最初的代码模型。
- QList<QString> list;
- //利用QSerialPortInfo类检测串口
- foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
- {
- list << info.portName(); //将找到的串口存入list容器
- }
- for(int i = 0;i <list.count();i++) //循环打开每一个串口,向其写入数据
- {
- QByteArray array = "checkdata";
- QSerialPort serialport;
- serialport.setPortName(list.at(i));
- if(!serialport_checkport.open(QIODevice::ReadWrite))
- {
- QMessageBox::warning(this,"error",QString("%1 can not open!").arg(serialport_checkport.portName()));
- return QString();
- }
- serialport.write(array); //写入数据
- QByteArray str = serialport.readAll(); //读取数据
- qDebug() << serialport.portName() << str;
- if(str.length())
- {
- qDebug() << "return data";
- break; //如果有返回数据则退出循环,该串口就是可用串口
- }
- array.clear();
- serialport.clear();
- serialport.close();
- }
上述代码只是简单实现了写入读取功能,但是运行发现,遍历了所有的串口后没有读取到串口返回的数据。
没有读取到数据的原因有两种,一是没有成功写入,二是写入了但是没有成功读取到数据。仔细检查代码觉得应该是没有读取到返回数据的原因。然后想到有可能是数据读取时间太快的原因,就在写入数据和读取数据中间加上了QTime,让程序暂停一段时间,并使用processEvents()函数继续处理事件。还有一种方法,利用了QTimer定时器和QEventloop类实现。
- //方法一
- QTime time;
- time.start();
- while (time.elapsed() < 500) //让程序等待一段时间后结束
- {
- QCoreApplication::processEvents(); //进入事件循环
- }
- //方法二
- QEventLoop eventloop;
- QTimer::singleShot(200, &eventloop, SLOT(quit())); //singleShot可以直接使用,不需要创建一个QTimer对象
- eventloop.exec(); //QEventLoop类让程序开启循环,使后面的代码等待运行,直到循环结束
在加入了QTime暂停程序后,虽然成功读取到了数据,但是读取的数据格式不对。
由于暂时未解决该乱码问题,通过打印数据长度发现返回的数据长度还是与写入的数据长度一致的,所以可以通过判断数据长度来确定串口。完整代码如下。
QList<QString> list; foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { list << info.portName(); //将找到的串口存入list容器 } for(int i = 0;i <list.count();i++) //循环打开每一个找到的串口 { QByteArray array = "checkdata"; QSerialPort serialport; serialport.setPortName(list.at(i)); if(!serialport_checkport.open(QIODevice::ReadWrite)) { QMessageBox::warning(this,"error",QString("%1 can not open!").arg(serialport_checkport.portName())); return QString(); } serialport.write(array); //写入数据 //方法一 // QTime time; // time.start(); // while (time.elapsed() < 500) // { // QCoreApplication::processEvents(); //让休眠的程序继续处理事件 // } //方法二 QEventLoop eventloop; QTimer::singleShot(200, &eventloop, SLOT(quit())); eventloop.exec(); QByteArray str = serialport.readAll(); //读取数据 qDebug() << serialport.portName() << str; if(str.length() == array.length()) //比较数据长度 { qDebug() << serialport.portName() << "是可用串口"; array.clear(); serialport.clear(); serialport.close(); return serialport.portName(); } array.clear(); serialport.clear(); serialport.close(); return QString(); }
联系客服