QT5串口通信(Hex格式传输)


参考博客

  1. 博客园-菜头大大:QT串口通信
  2. CSDN-宗师之路:QT实现串口通信(附源码下载)
  3. CSDN-xz-c:C++将10进制字符串转为16进制字符串

本文改进

  1. 在前辈们的代码基础上进行改进,使操作更符合逻辑
  2. 优化代码结构,提高了代码的可移植性

QT实现串口通信

  1. 在工程文件(.pro)中添加串口通信相关运行库:QT += serialport
  2. 在头文件中添加
     #include <QtSerialPort/QSerialPort>
     #include <QtSerialPort/QSerialPortInfo>
  3. 在头文件中定义全局的串口对象:QSerialPort *serial;

串口通信步骤

  1. 设置串口名称
    • 寻找可用串口
        void control::scanPort()
        {
            this->ui->cb_port->clear();
            int isHavePort = 0;
            foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
            {
                QSerialPort serial;
                serial.setPort(info);
                //判断端口能否打开
                if(serial.open(QIODevice::ReadWrite))
                {
                    this->ui->cb_port->addItem(serial.portName());
                    isHavePort ++;
                }
                if(isHavePort == 0){
                    QMessageBox::information(NULL, "警告", "没有可用串口");
                }
            }
        }
    • 设置串口名
        serial = new QSerialPort;
        //设置串口名
        serial->setPortName(this->ui->cb_port->currentText());
  2. 打开串口
     serial->open(QIODevice::ReadWrite);
  3. 设置波特率
     serial->setBaudRate(QSerialPort::Baud115200);//设置波特率为115200
  4. 设置数据位
     serial->setDataBits(QSerialPort::Data8);//设置数据位8
  5. 设置校验位
     serial->setParity(QSerialPort::NoParity); //无校验位
  6. 设置停止位
     serial->setStopBits(QSerialPort::OneStop);//停止位设置为1
  7. 设置流控制
     serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制
    通过上述操作,串口的基本设置就设置好了,接下来需要实现数据的接收和发送:
  8. 在打开串口按钮中执行的操作中添加槽函数,当下位机中有数据发送过来时就会相应这个槽函数
     connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
  9. 从上位机发送数据到下位机,发送内容位ASII码值或者为Hex格式;根据自身需求,我将数据进行了转换和格式化,此处为Hex格式。
     serial->write(QString2Hex(formatInput(hexStr)));

进制转换及格式化

由于下位机需求,需要两帧将数据发送过去,经过多番考虑,最终决定将十进制转换为16进制,然后以Hex进行发送

  1. 十进制转换为16进制字符串

     //将十进制int转换为十六进制字符串
     QString control::decInt2HexStr(int dec)
     {
         //保证数据在两帧范围内
         if(dec > 65535)
         {
             QMessageBox::information(NULL, "警告", "输入超出规定范围(input < 65535)");
             return "0";
         }
         QString hexStr;
         int temp = dec / 16;
         int left = dec % 16;
         if(temp > 0)
             hexStr += decInt2HexStr(temp);
         if(left < 10)
             hexStr += (left + '0');
         else
             hexStr += ('A' + left - 10);
         return hexStr;
     }
  2. 将字符串转换为Hex格式

     //字符串转Hex(QByteArray)类型
     QByteArray control::QString2Hex(QString hexStr)
     {
         QByteArray senddata;
         int hexdata, lowhexdata;
         int hexdatalen = 0;
         int len = hexStr.length();
         senddata.resize(len/2);
         char lstr, hstr;
         for(int i = 0; i < len; )
         {
             //将第一个不为' '的字符赋给hstr;
             hstr = hexStr[i].toLatin1();
             if(hstr == ' ')
             {
                 i++;
                 continue;
             }
             i++;
             //当i >= len时,跳出循环
             if(i >= len)
                 break;
             //当i < len时,将下一个字符赋值给lstr;
             lstr = hexStr[i].toLatin1();
             //将hstr和lstr转换为0-15的对应数值
             hexdata = ConvertHexChar(hstr);
             lowhexdata = ConvertHexChar(lstr);
             //
             if((hexdata == 16) || (lowhexdata == 16))
                 break;
             else
                 hexdata = hexdata * 16 + lowhexdata;
             i++;
             senddata[hexdatalen] = (char)hexdata;
             hexdatalen++;
         }
         senddata.resize(hexdatalen);
         return senddata;
     }
    
     //将单个字符串转换为hex
     //0-F -> 0-15
     char control::ConvertHexChar(char c)
     {
         if((c >= '0') && (c <= '9'))
             return c - 0x30;
         else if((c >= 'A') && (c <= 'F'))
             return c - 'A' + 10;//'A' = 65;
         else if((c >= 'a') && (c <= 'f'))
             return c - 'a' + 10;
         else
             return -1;
     }
  3. 输出形式格式化

     //将输入格式化,补满四位:0XFFFF
     QString control::formatInput(QString hexStr)
     {
         int strlen = hexStr.length();
         switch(strlen)
         {
             case 0:
                 hexStr = "0000";
                 break;
             case 1:
                 hexStr = "000" + hexStr;
                 break;
             case 2:
                 hexStr = "00" + hexStr;
                 break;
             case 3:
                 hexStr = "0" + hexStr;
                 break;
             case 4:
                 hexStr = hexStr;
                 break;
             default:
                 break;
         }
         return hexStr;
     }

UI展示

界面展示

源码下载:

Github


文章作者: Jason
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Jason !
  目录