zoukankan      html  css  js  c++  java
  • Qt开发串口

    首先,在工程文件里面,

    QT += serialport

    在头文件里面,

    #include <QSerialPort>

    1、配置打开串口

    QSerialPort* myserial = new QSerialPort():

    this->myserial->setPortName("COM1");//待打开的串口号

    this->myserial->setBaudRate(9600,QSerialPort::AllDirections);//设置波特率;QSerialPort::AllDirections:双工

    this->myserial->setDataBits(QSerialPort::Data8);//数据位

    this->myserial->setParity(QSerialPort::NoParity);//校验位

    this->myserial->setStopBits(QSerialPort::OneStop);//停止位

    this->myserial->setFlowControl(QSerialPort::NoFlowControl);//流控制

    this->myserial->open(QIODevice::ReadWrite);//打开串口

     2、发送数据

    char test[5] = {0x01,0x02,0x03,0x04,0x05};

    myserial.write(test);//发送

    3、接收数据

    定义一个函数作为槽函数,当接收缓冲区有数据的时候回调此函数。

    void ReadBuf()

    {

      QByteArray dataArray;

      dataArray = myserial->readAll();//读取数据

      if(!dataArray.isEmpty())

       {

        QString str;

        str = dataArray.toHex();//把数据直接转化为16进制的字符串形式

        ui->textEdit->setText(str);

       }

    }

     此外,在打开串口函数里面关联信号与槽。已知,当接收缓冲区有数据的时候,串口对象会发送readyRead信号。

    QObject::connect(myserial,&QSerialPort::readyRead,this,&MainWindow::ReadBuf);

    4、关闭串口

    this->myserial->close();

    备注一、自动获取可用串口号,并设置在QComboBox中

    1、需要包含头文件

    #include <QSettings>

    #include <qt_windows.h>

    2、自定义函数

    QString getcomm(int index, QString keyorvalue)

    {

       HKEY hKey;
        wchar_t keyname[256]; //键名数组
        char keyvalue[256];  //键值数组
        DWORD keysize,type,valuesize;
        int indexnum;
        QString commresult;
        if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\DEVICEMAP\SERIALCOMM"), 0, KEY_READ, &hKey) != 0)
        {
            QString error="Cannot open regedit!";
            return error;
        }
        QString keymessage;//键名
        QString message;
        QString valuemessage;//键值
        indexnum = index;//要读取键值的索引号
        keysize = sizeof(keyname);
        valuesize = sizeof(keyvalue);
        if (RegEnumValue(hKey, indexnum, keyname, &keysize, 0, &type, (BYTE*)keyvalue, &valuesize) == 0)
        {
            for (int i=0; i<(int)keysize; i++)
            {
                message = keyname[i];
                keymessage.append(message);
            }
            for (int j=0; j<(int)valuesize; j++)
            {
                if (keyvalue[j] != 0x00)
                    valuemessage.append(keyvalue[j]);
            }
            if (keyorvalue == "key")
                commresult = keymessage;
            if (keyorvalue == "value")
                commresult=valuemessage;
        }
        else
            commresult = "nokey";
        RegCloseKey(hKey);//关闭注册表
        return commresult;

    }

    3、将可用串口放在QComboBox里面

    void MainWindow::InitInterface()
    {
        QString path = "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM";
        QSettings *settings = new QSettings(path, QSettings::NativeFormat);
        QStringList key = settings->allKeys();
        QStringList comlist;
        comlist.clear();
        /* 取串口名 */
        for (int i=0; i<key.size(); i++)
            comlist << getcomm(i, "value");
        ui->comboBox->addItems(comlist);
    }

    PS:
    1、波特率9600意思是每秒最多传输9600/8=1200个字节;
    2、如何解决粘包:(以传输ascii为例)
    1)、接收数据,如果数据长度刚好为协议那么长,则直接解析
    2)、如果长度不正确就把此包追加到本地变量中,然后判断根据报文头的位置把本地变量去掉报文头前面的数据(QString::mid)
    3)、判断长度是否足够(并且本地变量的头是协议头),如果足够则取本地变量前n个数据进行解析,并将本地变量去掉这个包;如果不是协议头则清空此变量,再次进行循环

    PS:开发流程

    
    
  • 相关阅读:
    和园友们聊聊天
    php编写验证码
    面试题复习记录(二)
    面试题复习记录(一)
    正则表达式学习小记
    javascript学习小记(一)
    大四
    Java小应用程序
    明白这十个故事-->你也就参悟了人生
    Hibernate懒加载深入分析
  • 原文地址:https://www.cnblogs.com/judes/p/6664782.html
Copyright © 2011-2022 走看看