qt5串口通信

需要添加的内容 

使用qt中的串口通信的时候需要用到的两个头文件分别为:

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

QSerialPort 类提供了操作串口的各种接口。
QSerialPortInfo 是一个辅助类,可以提供计算机中可用串口的各种信息

 

还需要在工程文件中加下面一行代码:

QT       += serialport

 

代码 

遍历可用的串口

复制代码
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())      //遍历可用的窗口
    {
        //QSerialPortInfo::availablePorts()   获取所有端口的信息,返回值是一个QList<QSerialPortInfo>

        qDebug()<<"Name:"<<info.portName();  //返回串口名称
        qDebug()<<"Description:"<<info.description();  //返回串口说明
        qDebug() << "Manufacturer: " << info.manufacturer();  //返回制造商信息
        qDebug() << "Serial Number: " << info.serialNumber();  //返回串口连接设备的串口序列号
        /*通常,我们需要指定程序使用某一个确定的串口,这时不能只使用串口名称,因为USB串口每次插在不同
         的USB口上时获得的串口名称都可能有变化。这时可以利用串口的序列号,这个号码一般来说是唯一的
       */
        qDebug() << "System Location: " << info.systemLocation();  //系统本地位置
        
        


    }
复制代码

输出结果:

 

QSerialPort支持两种编程方法: 

1)*异步(非阻塞)方式。当控制权返回到Qt的事件循环中,相应的操作就会被调度和执行。当操作执行完了QSerial就会触发一个信号。例如:
QSerialPort::write()方法返回。当数据发送到串口,QSerialPort就会触发bytesWirtten()。
(2)*同步(阻塞)方式。在非GUI和多线程应用程序中,我们可以调用waitFor...()函数(例如QSerialPort::waitForReadyRead())使得调用线程在完成之前都是阻塞的。
阻塞的串口编程与非阻塞的串口编程是不一样的。阻塞的串口不许要事件循环,需要的代码很少。然而,在一个GUI应用程序中,阻塞的串口操作应该仅仅在非GUI线程中使用,避免用户界面冻结

 

QSerialPort 的串口操作 

选定串口后,要先打开串口,才能设置波特率等参数。这些参数都设置好了就可以使用了。最基本的操作无非是read() 和 write()。需要注意的是这两个操作都是非阻塞的

另外有一个重要的signal 也需要用到,那就是 void QIODevice::readyRead(),每次串口收到数据后都会发出这个signal。我们的程序中需要定义一个slot,并将其与这个signal 相连接。这样,每次新数据到来后,我们就可以在slot中读取数据了。这时一定要将串口缓冲区中的数据全部读出来,可以利用readAll() 来实现 

 

 

读取串口数据实例--超声波测距仪 

Win.cpp

复制代码
#include "win.h"

Win::Win(QWidget *parent)
    : QWidget(parent)
{

    str1="";
    i=0;

    this->resize(500,300);
    setWindowTitle("超声波测距仪- 明师软件");
    serial = new QSerialPort;

    label=new QLabel("距离:",this);
    label->move(50,100);
    label->setStyleSheet("font-size:50px;color:red;font-family:黑体 ");  //设置字体大小,字体颜色,字体

    label1=new QLabel("5   厘米",this);
    label1->move(200,100);
    label1->setStyleSheet("font-size:50px;color:red;font-family:黑体 ");


    QSerialPortInfo com_info;
    qDebug() << "Name : " << com_info.portName();  //串口名称默认是  ""
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            if( info.serialNumber() == "5573932333735170A1A2" )  //通过串口序列号来判断是否需要的设备
            {
                com_info = info;
                break;
            }
        }

    if (com_info.portName()==""){  //如果没找到超声波串口
      QMessageBox::critical(this,"错误","请把超声波测距仪插入USB口",QMessageBox::Ok);
      exit(0);  //退出程序

    }

        serial->setPort(com_info);  //设置要操作的串口
        if(serial->open(QIODevice::ReadWrite))   //如果串口打开成功
            //以读写方式打开串口
        {
           qDebug() << "成功打开串口";
           serial->setBaudRate(QSerialPort::Baud9600); //设置波特率
           /*常用波特率
           常量                            值                说明
          QSerialPort::Baud1200          1200            1200 baud.
          QSerialPort::Baud2400          2400            2400 baud.
          QSerialPort::Baud4800          4800            4800 baud.
          QSerialPort::Baud9600          9600            9600 baud.
          QSerialPort::Baud19200         19200           19200 baud.
          QSerialPort::Baud38400         38400           38400 baud.
          QSerialPort::Baud57600         57600           57600 baud.
          QSerialPort::Baud115200        115200          115200 baud.
          */
           serial->setParity(QSerialPort::NoParity);  //设置校验位
           serial->setDataBits(QSerialPort::Data8);  //设置数据位
           serial->setStopBits(QSerialPort::OneStop);  //设置停止位
           serial->setFlowControl(QSerialPort::NoFlowControl);   //设置流控制

           //serial->clearError();
           /*此属性保存串行端口的错误状态I/O设备状态返回错误代码。例如,如果open()返回false,或者读/写操作返回-1,
           则可以使用此属性找出操作失败的原因。调用clearError()后,错误代码被设置为默认的QSerialPort::NoError
           */
           //serial->clear();
           /*
           清除输出或输入缓冲区中的所有字符。这包括清除内部类缓冲区和UART(驱动程序)缓冲区。
           同时终止挂起的读或写操作。如果成功,则返回true;否则返回false
           */
           connect(serial, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); //如果接收到数据输入信号,就执行相应的槽函数
        }




}

Win::~Win()
{
}

void Win::readyReadSlot()
{

    QByteArray arr = serial->readAll(); //读取串口缓冲区数据
    //读取后的数据类型:QByteArray
    str = arr; //转换成QString
    str1=str1+str;

    i=str1.count("\r\n");//获取子串出现的次数
    if(i>=2){
        //qDebug() <<str1<<i;
        list = str1.split("\r\n");  //把字符串拆分成QStringList

        str=list[1]+"厘米";
        label1->setText(str);
        label1->adjustSize();//    根据内容自适应大小



        str1="";
            }


}
复制代码

 

win.h

复制代码
#ifndef WIN_H
#define WIN_H

#include <QWidget>
#include <QDebug>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QLabel>
 #include <QMessageBox>



class Win : public QWidget
{
    Q_OBJECT

public:
    Win(QWidget *parent = nullptr);
    ~Win();

    QSerialPort *serial;  //定义一个全局的串口对象指针

    QLabel* label;
    QLabel* label1;
    QString str;
    QString str1;
    int i;
    QStringList list;


public slots:
    void readyReadSlot();

};
#endif // WIN_H
复制代码

工程下载:链接:https://pan.baidu.com/s/1meJqogbWZ-KDTqU52jw0rQ    提取码:6666    

 

 

 学习资料:https://blog.csdn.net/u010780613/article/details/50560126   

                  https://blog.csdn.net/lmhuanying1012/article/details/78747737

posted @   天子骄龙  阅读(822)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示

目录导航