打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Qt串口助手(1)
userphoto

2022.10.02 北京

关注

        在使用qt编写串口助手时,想要做一个自动寻找串口的功能,因为项目所使用的开发板会返回从串口写入的数据,所以根据此特性,可以做一个自动寻找可用串口的功能。下面是最初的代码模型。

  1. QList<QString> list;
  2. //利用QSerialPortInfo类检测串口
  3. foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  4. {
  5. list << info.portName(); //将找到的串口存入list容器
  6. }
  7. for(int i = 0;i <list.count();i++) //循环打开每一个串口,向其写入数据
  8. {
  9. QByteArray array = "checkdata";
  10. QSerialPort serialport;
  11. serialport.setPortName(list.at(i));
  12. if(!serialport_checkport.open(QIODevice::ReadWrite))
  13. {
  14. QMessageBox::warning(this,"error",QString("%1 can not open!").arg(serialport_checkport.portName()));
  15. return QString();
  16. }
  17. serialport.write(array); //写入数据
  18. QByteArray str = serialport.readAll(); //读取数据
  19. qDebug() << serialport.portName() << str;
  20. if(str.length())
  21. {
  22. qDebug() << "return data";
  23. break; //如果有返回数据则退出循环,该串口就是可用串口
  24. }
  25. array.clear();
  26. serialport.clear();
  27. serialport.close();
  28. }

        上述代码只是简单实现了写入读取功能,但是运行发现,遍历了所有的串口后没有读取到串口返回的数据。 

        没有读取到数据的原因有两种,一是没有成功写入,二是写入了但是没有成功读取到数据。仔细检查代码觉得应该是没有读取到返回数据的原因。然后想到有可能是数据读取时间太快的原因,就在写入数据和读取数据中间加上了QTime,让程序暂停一段时间,并使用processEvents()函数继续处理事件。还有一种方法,利用了QTimer定时器和QEventloop类实现。

  1. //方法一
  2. QTime time;
  3. time.start();
  4. while (time.elapsed() < 500) //让程序等待一段时间后结束
  5. {
  6. QCoreApplication::processEvents(); //进入事件循环
  7. }
  8. //方法二
  9. QEventLoop eventloop;
  10. QTimer::singleShot(200, &eventloop, SLOT(quit())); //singleShot可以直接使用,不需要创建一个QTimer对象
  11. eventloop.exec(); //QEventLoop类让程序开启循环,使后面的代码等待运行,直到循环结束

 在加入了QTime暂停程序后,虽然成功读取到了数据,但是读取的数据格式不对。     

 由于暂时未解决该乱码问题,通过打印数据长度发现返回的数据长度还是与写入的数据长度一致的,所以可以通过判断数据长度来确定串口。完整代码如下。

  1. QList<QString> list;
  2. foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  3. {
  4. list << info.portName(); //将找到的串口存入list容器
  5. }
  6. for(int i = 0;i <list.count();i++) //循环打开每一个找到的串口
  7. {
  8. QByteArray array = "checkdata";
  9. QSerialPort serialport;
  10. serialport.setPortName(list.at(i));
  11. if(!serialport_checkport.open(QIODevice::ReadWrite))
  12. {
  13. QMessageBox::warning(this,"error",QString("%1 can not open!").arg(serialport_checkport.portName()));
  14. return QString();
  15. }
  16. serialport.write(array); //写入数据
  17. //方法一
  18. // QTime time;
  19. // time.start();
  20. // while (time.elapsed() < 500)
  21. // {
  22. // QCoreApplication::processEvents(); //让休眠的程序继续处理事件
  23. // }
  24. //方法二
  25. QEventLoop eventloop;
  26. QTimer::singleShot(200, &eventloop, SLOT(quit()));
  27. eventloop.exec();
  28. QByteArray str = serialport.readAll(); //读取数据
  29. qDebug() << serialport.portName() << str;
  30. if(str.length() == array.length()) //比较数据长度
  31. {
  32. qDebug() << serialport.portName() << "是可用串口";
  33. array.clear();
  34. serialport.clear();
  35. serialport.close();
  36. return serialport.portName();
  37. }
  38. array.clear();
  39. serialport.clear();
  40. serialport.close();
  41. return QString();
  42. }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
C#中如何安全的关闭串口(By?Kiseigo)
手机通过蓝牙串口与arduino通信
VB.NET开发全功能串口调试助手 (含完整工程)
android串口通信以及串口协议解析
串口通信精华帖
Qt中如何针对串口大数据量通信进行流式处理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服