QT5串口编程

Posted 宁静致远2021

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT5串口编程相关的知识,希望对你有一定的参考价值。

这里使用了QSerialPort模块提供的两个类:QSerialPort类和QSerialPortInfo类,QSerialPort类提供了对串口的操作,QSerialPortInfo类提供了对串口信息的获取。下面是主要代码,包含了对串口类的简单使用。

1 添加库,添加类

首先,一定要在.pro文件中添加:QT += serialport

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

QT       += serialport

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

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

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

2 设置和打开串口

串口初始化如下:

/****************************串口初始化*****************************/
void MainWindow::initPort()

    //读取串口信息
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    
        qDebug()<<"Name:"<<info.portName();
        qDebug()<<"Description:"<<info.description();
        qDebug()<<"Manufacturer:"<<info.manufacturer();
 
        //这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        
            //将串口号添加到cmb
            ui->cmbPortName->addItem(info.portName());
            //关闭串口等待人为(打开串口按钮)打开
            serial.close();
        
    
 
    QStringList baudList;//波特率
    QStringList parityList;//校验位
    QStringList dataBitsList;//数据位
    QStringList stopBitsList;//停止位
 
    baudList<<"50"<<"75"<<"100"<<"134"<<"150"<<"200"<<"300"
           <<"600"<<"1200"<<"1800"<<"2400"<<"4800"<<"9600"
          <<"14400"<<"19200"<<"38400"<<"56000"<<"57600"
         <<"76800"<<"115200"<<"128000"<<"256000";
 
    ui->cmbBaudRate->addItems(baudList);
    ui->cmbBaudRate->setCurrentIndex(12);
 
    parityList<<"无"<<"奇"<<"偶";
    parityList<<"标志";
    parityList<<"空格";
 
    ui->cmbParity->addItems(parityList);
    ui->cmbParity->setCurrentIndex(0);
 
    dataBitsList<<"5"<<"6"<<"7"<<"8";
    ui->cmbDataBits->addItems(dataBitsList);
    ui->cmbDataBits->setCurrentIndex(3);
 
    stopBitsList<<"1";
    stopBitsList<<"1.5";
    stopBitsList<<"2";
 
    ui->cmbStopBits->addItems(stopBitsList);
    ui->cmbStopBits->setCurrentIndex(0);
 
    //设置按钮可以被按下
    ui->btnOpen->setCheckable(true);

这里通过遍历所有串口将我们需要使用的串口添加到了combox中,如果想要手动选择可以将串口名称通过列表的方式添加到combox中,到使用的时候再选择 。

串口设置如下:

/****************************串口设置******************************/
void MainWindow::on_btnOpen_clicked()

    if(ui->btnOpen->text() == "打开串口")
    
        my_serialport = new QSerialPort(this);
 
        //设置串口号
        my_serialport->setPortName(ui->cmbPortName->currentText());
        //以读写方式打开串口
        if(my_serialport->open(QIODevice::ReadWrite))
        
            //设置波特率
            my_serialport->setBaudRate(ui->cmbBaudRate->currentText().toInt());
            //设置数据位
            my_serialport->setDataBits(QSerialPort::Data8);
            //设置校验位
            my_serialport->setParity(QSerialPort::NoParity);
            //设置流控制
            my_serialport->setFlowControl(QSerialPort::NoFlowControl);
            //设置停止位
            my_serialport->setStopBits(QSerialPort::OneStop);
 
            //每秒读一次
            timer = new QTimer(this);
            connect(timer, SIGNAL(timeout()), this, SLOT(readComDataSlot()));
            timer->start(1000);
 
            setNonSelectable();
        
        else
        
            QMessageBox::about(NULL, "提示", "串口没有打开!");
            return;
        
    
    else
    
        timer->stop();
        setSelectable();
        my_serialport->close();
    

#include "widget.h"
#include "ui_widget.h"
#include <QLayout>

#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)

    ui->setupUi(this);
    m_serialPort = new QSerialPort();

    initUI();

    m_portNameList = getPortNameList();

    m_PortNameComboBox->addItems(m_portNameList);

    connect(m_OpenPortButton,&QPushButton::clicked,this,&Widget::openPort);



Widget::~Widget()

    if (m_serialPort->isOpen())
    
        m_serialPort->close();
    
    delete m_serialPort;

    delete ui;


void Widget::initUI()

    this->setWindowTitle("码农小明 test QSerialPort");

    m_OpenPortButton = new QPushButton();
    m_OpenPortButton->setText("打开串口");

    m_PortNameComboBox  = new QComboBox();

    QHBoxLayout *m_layout = new QHBoxLayout();

    m_layout->addWidget(m_PortNameComboBox);
    m_layout->addWidget(m_OpenPortButton);

    this->setLayout(m_layout);


QStringList Widget::getPortNameList()

    QStringList m_serialPortName;
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    
        m_serialPortName << info.portName();
        qDebug()<<"serialPortName:"<<info.portName();
    
    return m_serialPortName;


void Widget::openPort()

    if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
    
        m_serialPort->clear();
        m_serialPort->close();
    


    m_serialPort->setPortName(m_PortNameComboBox->currentText());//当前选择的串口名字

    if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
    
        qDebug()<<"打开失败!";
        return;
    
    qDebug()<<"串口打开成功!";

    m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
    m_serialPort->setDataBits(QSerialPort::Data8);      //数据位为8位
    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
    m_serialPort->setParity(QSerialPort::NoParity); //无校验位
    m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位

    connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));


//接收到单片机发送的数据进行解析
void Widget::receiveInfo()

    QByteArray info = m_serialPort->readAll();

    qDebug()<<"receive info:"<<info;


原文链接:
https://shenmingyi.blog.csdn.net/article/details/81669540?spm=1001.2101.3001.6650.16&utm_medium=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-16.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-16.no_search_link

3 读取数据

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

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

//连接信号和槽
QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
//……
//编写的槽函数
void MainWindow::serialPort_readyRead()

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

这里是对串口的设置,需要先打开串口才能设置串口参数。参数设置好之后就可以通过read()和write()函数进行数据的读写,我这里用的是1秒的定时器来读缓冲区的数据。

数据收发如下:

/****************************数据传输******************************/
void MainWindow::readComDataSlot()

    //读取串口数据
    QByteArray readComData = my_serialport->readAll();
 
    //将读到的数据显示到数据接收区的te中
    if(readComData != NULL)
    
        ui->teReceiveData->append(readComData);
    
 
    //清除缓冲区
    readComData.clear();

 
void MainWindow::on_btnSend_clicked()

    //获取发送区的数据
    QString sendData = ui->teSendData->toPlainText();
    QByteArray sendData_2 = sendData.toLatin1();
 
    //写入缓冲区
    my_serialport->write(sendData_2);


4 发送数据

serial->write(data);

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

//串口接收
void MainWindow::serialPort_readyRead()

    //从接收缓冲区中读取数据
    QByteArray buffer = serial.readAll();
    //从界面中读取以前收到的数据
    QString recv = ui->textEdit->toPlainText();
    recv += QString(buffer);
    //清空以前的显示
    ui->textEdit->clear();
    //重新显示
    ui->textEdit->append(recv);

5 关闭串口

serial->close();

原文链接:
https://blog.csdn.net/qq_41068712/article/details/89317764?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163763632016780357243611%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163763632016780357243611&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-89317764.pc_search_result_control_group&utm_term=qt5+%E4%B8%B2%E5%8F%A3&spm=1018.2226.3001.4187

https://blog.csdn.net/zbw1185/article/details/51496663#

以上是关于QT5串口编程的主要内容,如果未能解决你的问题,请参考以下文章

Qt5 串口类QSerialPort

QT5 串口收发实例代码

第14章 基于QT5串口设备开发

QT5 串口操作

怎么判断串口已发送完毕?(qt5, c++)

在 Qt4 中使用最新的 Qt5 串口库