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);//设置为无流控制
    

通过上述操作,串口的基本设置就设置好了,接下来需要实现数据的接收和发送:

  1. 在打开串口按钮中执行的操作中添加槽函数,当下位机中有数据发送过来时就会相应这个槽函数
    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
    
  2. 从上位机发送数据到下位机,发送内容位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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容