分享

QT5串口编程

 goodwangLib 2020-05-03

注:更新自2018年12月13日(我回看了一年多前写的这篇博客,觉得不是很好,故翻新了一遍。)

最近在学习嵌入式,而上位机又是一个不可缺少的工具,于是就开始接触QT,学习编写上位机。刚开始的时候什么都不懂,发现《Qt 学习之路 2》有比较好的入门教程。学习了前面部分,对QT有了大概的了解后,就开始在网上寻找串口编程的方法。通过好几天的学习,终于写出了一个用于串口通信的上位机。下面开始介绍串口类的使用。

首先,QT5是自带QSerialPort这个类的,使用时需要在pro文件里面添加一行:

QT       += serialport

然后直接引用头文件就可以了。

  1. #include <QSerialPort> //提供访问串口的功能 
  2. #include <QSerialPortInfo> //提供系统中存在的串口的信息

在QT5中,串口通信是借助一个QSerialPort的对象来实现的,在设置QSerialPort对象对串口的名称、波特率、数据位、校验位、停止位等参数后,方能对串口进行读写。下面,我总结了一下借助QSerailPort对串口进行设置、打开、读、写和关闭的过程。


一、设置和打开串口

  1. //创建串口对象
  2. QSerialPort serial;
  3. //设置串口名
  4. serial.setPortName("COM3");
  5. //设置波特率
  6. serial.setBaudRate(QSerialPort::Baud9600);
  7. //设置数据位数
  8. serial.setDataBits(QSerialPort::Data8);
  9. //设置奇偶校验
  10. serial.setParity(QSerialPort::NoParity);
  11. //设置停止位
  12. serial.setStopBits(QSerialPort::OneStop);
  13. //设置流控制
  14. serial.setFlowControl(QSerialPort::NoFlowControl);
  15. //打开串口
  16. serial.open(QIODevice::ReadWrite);

以上代码是QSerialPort对象的设置示例,作用是:

  • 设置串口名为 COM3 
  • 设置波特率为9600
  • 设置数据位为8位
  • 设置没有奇偶校验位
  • 设置停止位为1位
  • 设置没有流控制
  • 以可读写的方式打开串口

设置完这些就能进行读写操作了。如果遇到不理解的地方,可以选择QT的类或函数,然后按F1查阅手册。举个例子,如果我们想查看QSerialPort的其它的属性,可以选择QSerialPort的类名成员函数,然后按F1。


二、读取数据

  1. //从接收缓冲区中读取数据
  2. QByteArray buffer = serial.readAll();

串口在收到数据后,会将数据存入接收缓冲区。此时,我们可以通过readAll()函数将接收缓冲区的数据读出来。当串口的接收缓冲区有数据时,QSerilaPort对象会发出一个readyRead()的信号。因此,我们可以编写一个槽函数来读数据,例如:

  1. //连接信号和槽
  2. QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
  3. ……
  4. //编写的槽函数
  5. void MainWindow::serialPort_readyRead()
  6. {
  7. //从接收缓冲区中读取数据
  8. QByteArray buffer = serial.readAll();
  9. //处理数据
  10. //……
  11. }

三、发送数据

serial->write(data);

使用write函数便可以把字节数组中的字节发送出去。

四、关闭串口

serial->close();

串口不用时,可通过close()函数将其关闭。

 

接下来是一个实例

1、创建一个新的Widgets Appliaction工程

2、使用QtCreator的ui文件来设计上位机的界面,设计如下:

3、mainwindow.h文件内容如下:

  1. //mainwindow.h
  2. #ifndef MAINWINDOW_H
  3. #define MAINWINDOW_H
  4. #include <QMainWindow>
  5. #include <QSerialPort>
  6. #include <QSerialPortInfo>
  7. namespace Ui {
  8. class MainWindow;
  9. }
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13. public:
  14. explicit MainWindow(QWidget *parent = 0);
  15. ~MainWindow();
  16. private slots:
  17. void serialPort_readyRead();
  18. void on_searchButton_clicked();
  19. void on_openButton_clicked();
  20. void on_sendButton_clicked();
  21. void on_clearButton_clicked();
  22. private:
  23. Ui::MainWindow *ui;
  24. QSerialPort serial;
  25. };
  26. #endif // MAINWINDOW_H

4、mainwindow.cpp文件内容如下:

  1. //mainwindow.cpp
  2. #include "mainwindow.h"
  3. #include "ui_mainwindow.h"
  4. #include <QMessageBox>
  5. MainWindow::MainWindow(QWidget *parent) :
  6. QMainWindow(parent),
  7. ui(new Ui::MainWindow)
  8. {
  9. ui->setupUi(this);
  10. //连接信号和槽
  11. QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
  12. //发送按键失能
  13. ui->sendButton->setEnabled(false);
  14. //波特率默认选择下拉第三项:9600
  15. ui->baudrateBox->setCurrentIndex(3);
  16. }
  17. MainWindow::~MainWindow()
  18. {
  19. delete ui;
  20. }
  21. void MainWindow::serialPort_readyRead()
  22. {
  23. //从接收缓冲区中读取数据
  24. QByteArray buffer = serial.readAll();
  25. //从界面中读取以前收到的数据
  26. QString recv = ui->recvTextEdit->toPlainText();
  27. recv += QString(buffer);
  28. //清空以前的显示
  29. ui->recvTextEdit->clear();
  30. //重新显示
  31. ui->recvTextEdit->append(recv);
  32. }
  33. void MainWindow::on_searchButton_clicked()
  34. {
  35. ui->portNameBox->clear();
  36. //通过QSerialPortInfo查找可用串口
  37. foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
  38. {
  39. ui->portNameBox->addItem(info.portName());
  40. }
  41. }
  42. void MainWindow::on_openButton_clicked()
  43. {
  44. if(ui->openButton->text()==QString("打开串口"))
  45. {
  46. //设置串口名
  47. serial.setPortName(ui->portNameBox->currentText());
  48. //设置波特率
  49. serial.setBaudRate(ui->baudrateBox->currentText().toInt());
  50. //设置数据位数
  51. switch(ui->dataBitsBox->currentIndex())
  52. {
  53. case 8: serial.setDataBits(QSerialPort::Data8); break;
  54. default: break;
  55. }
  56. //设置奇偶校验
  57. switch(ui->ParityBox->currentIndex())
  58. {
  59. case 0: serial.setParity(QSerialPort::NoParity); break;
  60. default: break;
  61. }
  62. //设置停止位
  63. switch(ui->stopBitsBox->currentIndex())
  64. {
  65. case 1: serial.setStopBits(QSerialPort::OneStop); break;
  66. case 2: serial.setStopBits(QSerialPort::TwoStop); break;
  67. default: break;
  68. }
  69. //设置流控制
  70. serial.setFlowControl(QSerialPort::NoFlowControl);
  71. //打开串口
  72. if(!serial.open(QIODevice::ReadWrite))
  73. {
  74. QMessageBox::about(NULL, "提示", "无法打开串口!");
  75. return;
  76. }
  77. //下拉菜单控件失能
  78. ui->portNameBox->setEnabled(false);
  79. ui->baudrateBox->setEnabled(false);
  80. ui->dataBitsBox->setEnabled(false);
  81. ui->ParityBox->setEnabled(false);
  82. ui->stopBitsBox->setEnabled(false);
  83. ui->openButton->setText(QString("关闭串口"));
  84. //发送按键使能
  85. ui->sendButton->setEnabled(true);
  86. }
  87. else
  88. {
  89. //关闭串口
  90. serial.close();
  91. //下拉菜单控件使能
  92. ui->portNameBox->setEnabled(true);
  93. ui->baudrateBox->setEnabled(true);
  94. ui->dataBitsBox->setEnabled(true);
  95. ui->ParityBox->setEnabled(true);
  96. ui->stopBitsBox->setEnabled(true);
  97. ui->openButton->setText(QString("打开串口"));
  98. //发送按键失能
  99. ui->sendButton->setEnabled(false);
  100. }
  101. }
  102. void MainWindow::on_sendButton_clicked()
  103. {
  104. //获取界面上的数据并转换成utf8格式的字节流
  105. QByteArray data = ui->sendTextEdit->toPlainText().toUtf8();
  106. serial.write(data);
  107. }
  108. void MainWindow::on_clearButton_clicked()
  109. {
  110. ui->recvTextEdit->clear();
  111. }

5、main.cpp文件内容如下:

  1. #include "mainwindow.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. MainWindow w;
  7. w.show();
  8. return a.exec();
  9. }

4、测试(将USB转TTL模块发送和接收引脚短接,自己发自己收)

 

新的工程已经上传至:https://download.csdn.net/download/u014695839/10881180 (2018年12月27日更新)

以前的工程在这里可以下载:http://download.csdn.net/detail/u014695839/9763670

以上内容若有问题,大家务必提醒,我定会马上更正!

希望能与大家多多交流。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多