zoukankan      html  css  js  c++  java
  • 46.QT-自带库QSerialPort串口使用

    之前一章学习的是第三方库使用: 34.QT-qextserialport第三方库制作串口助手(并动态检测在线串口,附带源码)

    本章来学习自带serial库

    1.QSerialPortInfo

    QList<QSerialPortInfo>  QSerialPortInfo::availablePorts();      
             //获取当前在线的串口设备

    示例如下:

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
    
            qDebug() << "Name : " << info.portName();
    
            qDebug() << "Description : " << info.description();
    
            qDebug() << "Manufacturer: " << info.manufacturer();
    
            qDebug() << "Serial Number: " << info.serialNumber();
    
            qDebug() << "System Location: " << info.systemLocation();
    }

    2.QSerialPort初始化

    初始化如下所示:

    serialport.setPortName(cfg.portName);
    serialport.setBaudRate(QSerialPort::Baud115200);
    serialport.setParity(QSerialPort::NoParity);
    serialport.setDataBits(QSerialPort::Data8);
    serialport.setStopBits(QSerialPort::OneStop);
    serialport.setFlowControl(QSerialPort::NoFlowControl);
    if(!serialport.open(QIODevice::ReadWrite))
    {
          qDebug()<<"打开失败";
          return;
    }

     

    3.QSerialPort信号介绍

    void readyRead();           
    //当串口接收到下位机发送数据时,将会发送该信号,然后我们在对应的槽函数调用serialport .readAll()即可
    
    error(QSerialPort::SerialPortError );
    //串口错误信号,比如当串口打开失败,串口连接时突然断开,都将会调用该信号
    //比如:  QSerialPort::PermissionError (表示串口连接断开了)

     

    4.QSerialPort示例

    Widget::Widget(QWidget *parent)
        : QWidget(parent),
          serialport(this),
          btn("发送",this)
    {
        serialport.setPortName("COM21");
        serialport.setBaudRate(QSerialPort::Baud115200);
        serialport.setParity(QSerialPort::NoParity);
        serialport.setDataBits(QSerialPort::Data8);
        serialport.setStopBits(QSerialPort::OneStop);
        serialport.setFlowControl(QSerialPort::NoFlowControl);
        if(!serialport.open(QIODevice::ReadWrite))
        {
              qDebug()<<"打开失败";
              return;
        }
        connect(&serialport,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
        connect(&btn,SIGNAL(clicked()),this,SLOT(sendSerialData()));  
    }
    
    void Widget::onReadyRead()
    {
        QString str(serialport.readAll());
        qDebug()<<str;
    }
    void Widget::sendSerialData()
    {
         serialport.write(QString("发送:%1
    ").arg(qrand()).toLocal8Bit());    //发送随机值
    }

    运行打印:

     

    发现下位机发送上来的是乱码的,这是因为我们下位机程序是用的gbk编码写的,所以打印汉字乱码了

     

    5.修改代码-添加数据格式编码转换

    修改发送/接收函数:

    void Widget::onReadyRead()
    {
         QString str(fromGBKtoUtf8(serialport.readAll()));
         QStringList  list = str.split(QRegExp("[
    ]"), QString::SkipEmptyParts);      //去掉
     , SkipEmptyParts表示如果末尾为
    则不需要打印
    
         foreach (QString line, list) {
           qDebug()<<line;
        }
    }
    
    void Widget::sendSerialData()
    {
        //serialport.write(QString("%1
    ").arg(qrand()).toLocal8Bit());
         serialport.write(fromUtf8toGBK(QString("%1
    ").arg(qrand())));
    }
    
    QString  Widget::fromGBKtoUtf8(QByteArray arry)
    {
        QTextCodec *gbk = QTextCodec::codecForName("gbk");
        QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
    
        QString unicode=gbk->toUnicode(arry);
        return QString(utf8->fromUnicode(unicode));
    }
    
    QByteArray Widget::fromUtf8toGBK(QString str)
    {
        QTextCodec *gbk = QTextCodec::codecForName("gbk");
        QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");
        QString unicode=utf8->toUnicode(str.toLocal8Bit());
        return gbk->fromUnicode(unicode);
    }

    运行打印:

     

    6.在QThread线程中使用QSerialPort

    由于在QThread线程里不能用槽函数,不过可以在run里使用QSerialPort::waitForReadyRead()来阻塞获取读数据.如果在指定时间内读取成功/失败,则向界面发送数据.

    示例如下:

           serialport.write( QString("%1
    ").arg(qrand()).toLocal8Bit() );    //写入随机值
           if(serialport.waitForBytesWritten(100))  //100ms 等待写入成功
           {
                if(serialport.waitForReadyRead(100))  //等待数据返回
                {
                    QString str((serialport.readAll()));
                    QStringList  list = str.split(QRegExp("[
    ]"),QString::SkipEmptyParts);      //去掉
    
    
                    foreach (QString line, list) {
    
                      qDebug()<<line;
    
                      //解析line,并向界面发送信号 ... ...
                   }
                }
                else
                   qDebug()<<"read err";
           }
           else
              qDebug()<<"write err";

     

  • 相关阅读:
    PyQt5复杂控件(树控件、选项卡控件(滚动条控件、多文档控件、停靠控件)
    PyQt5单元格操作大全
    PyQt5打印机
    PyQt5剪切板操作
    PyQt5的菜单栏、工具栏和状态栏
    PyQt5日历控件及相关操作
    PyQt5控件支持拖拽方法
    《Lua程序设计》第3章 表达式 学习笔记
    Lua中的table构造式(table constructor)
    《Lua程序设计》第2章 类型与值 学习笔记
  • 原文地址:https://www.cnblogs.com/lifexy/p/10960032.html
Copyright © 2011-2022 走看看