Qt实现串口助手

本文实例为大家分享了Qt实现串口助手的具体代码,供大家参考,具体内容如下

1.界面布局

这是一个常见的串口助手布局。要说有什么不常见,大概就是发送可以选择编码方式:GBK/UTF8

2.要点

没什么难度,就是水磨工夫,一点点写。容易错处的地方都写在代码注释里。

3.代码

下面是 mainwindow.cpp 文件。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <qdebug.h>
 
QSerialPort *serial;
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    serial = new QSerialPort;
 
    findSerialPort();
 
    ui->cbbBaudrate->addItem(QStringLiteral("4800"), QSerialPort::Baud4800);
    ui->cbbBaudrate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
    ui->cbbBaudrate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
    ui->cbbBaudrate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
    ui->cbbBaudrate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
    ui->cbbBaudrate->setCurrentIndex(4);
    //添加数据位
     ui->cbbDataSize->addItem(QStringLiteral("5"), QSerialPort::Data5);
     ui->cbbDataSize->addItem(QStringLiteral("6"), QSerialPort::Data6);
     ui->cbbDataSize->addItem(QStringLiteral("7"), QSerialPort::Data7);
     ui->cbbDataSize->addItem(QStringLiteral("8"), QSerialPort::Data8);
     ui->cbbDataSize->setCurrentIndex(3);
     //添加奇偶校验位
     ui->cbbParity->addItem(tr("None"), QSerialPort::NoParity);
     ui->cbbParity->addItem(tr("Even"), QSerialPort::EvenParity);
     ui->cbbParity->addItem(tr("Odd"), QSerialPort::OddParity);
     ui->cbbParity->addItem(tr("Mark"), QSerialPort::MarkParity);
     ui->cbbParity->addItem(tr("Space"), QSerialPort::SpaceParity);
     ui->cbbParity->setCurrentIndex(0);
     //添加停止位
     ui->cbbStopbit->addItem(QStringLiteral("1"), QSerialPort::OneStop);
     ui->cbbStopbit->addItem(QStringLiteral("1.5"), QSerialPort::OneAndHalfStop);//
     ui->cbbStopbit->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
     ui->cbbStopbit->setCurrentIndex(0);
     //添加流控位
     ui->cbbFlowbit->addItem(tr("None"), QSerialPort::NoFlowControl);
     ui->cbbFlowbit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
     ui->cbbFlowbit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
     ui->cbbFlowbit->setCurrentIndex(0);
     //禁用发送按钮
     ui->btnSend->setEnabled(false);
 
     ui->btnOpen->setStatusTip(tr("打开/关闭串口"));
     ui->rdbGbk->setStatusTip("以GBK编码发送" );
     ui->rdbUtf8->setStatusTip(tr("以UTF8编码发送"));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::findSerialPort()
{
    ui->cbbPort->clear();
    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        QSerialPort tempserial;
        tempserial.setPort(info);
 
        if(tempserial.open(QIODevice::ReadWrite))
        {
            ui->cbbPort->addItem(info.description()+":"+tempserial.portName(),tempserial.portName());
 
            tempserial.close();
        }
    }
}
 
void MainWindow::setsuienable( bool en )
{
    ui->cbbPort->setEnabled(en);
    ui->cbbBaudrate->setEnabled(en);
    ui->cbbDataSize->setEnabled(en);
    ui->cbbParity->setEnabled(en);
    ui->cbbStopbit->setEnabled(en);
    ui->cbbFlowbit->setEnabled(en);
}
 
void MainWindow::on_btnOpen_clicked()
{
    if(ui->btnOpen->text()  != "关闭")
    {
        if( !ui->cbbPort->currentText().isNull() )
        {
 
            ui->btnOpen->setText("关闭");
            ui->btnSend->setEnabled(true);
            ui->btnFind->setEnabled(false);
            setsuienable(false);
 
            serial->setPortName(ui->cbbPort->currentData(Qt::UserRole).value<QString>()  );
            serial->setBaudRate(ui->cbbBaudrate->currentData(Qt::UserRole).value<qint32>() );
            serial->setDataBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::DataBits>() );
            serial->setFlowControl(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::FlowControl>() );
            serial->setParity(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::Parity>() );
            serial->setStopBits(ui->cbbDataSize->currentData(Qt::UserRole).value<QSerialPort::StopBits>() );
            serial->open(QIODevice::ReadWrite);
 
 
            connect(serial, &QSerialPort::readyRead, this, &MainWindow::serialReadData);
        }
    }
    else
    {
        serial->close();
        setsuienable(true);
        ui->btnSend->setEnabled(false);
        ui->btnOpen->setText("打开");
        ui->btnFind->setEnabled(true);
    }
}
 
//字符串数据转为HEX,16进制形式。譬如将 “30”转为“0”
bool StringToHex( QString &dst,const QString src )
{
    QStringList list = src.trimmed().split(QRegExp("\t|\n|\r\n|\r| |,|;")); //去除头尾空白,再分割
 
    foreach (QString n,  list )
    {
        bool res;
        if(n.isEmpty())continue;
        int d= n.toInt(&res,16);
        if(d>255){  return  false ;}
 
        char  c = d;
        if(res)
            dst.append(c);
        else
            return  false ;
    }
    return true;
}
//UTF8转为GBK
QByteArray Utf8ToGbk(QByteArray buf)
{
    QTextCodec* Utf8Codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(Utf8Codec);
    QTextCodec* GbkCodec = QTextCodec::codecForName("GBK");
 
    QByteArray ByteGbk = GbkCodec->fromUnicode( Utf8Codec->toUnicode( buf ) );   //先Unicode编码,后arr
 
    return  ByteGbk ;
}
//串口发送
void MainWindow::on_btnSend_clicked()
{
    if( ui->teSend->toPlainText() .isEmpty() )return;
 
    if( ui->ckbSendhex->isChecked()  )
    {
        QString txt;
        if( StringToHex( txt ,ui->teSend->toPlainText() ) )
        {
            serial->write( txt.toLatin1()  );
        }else
        {
            QMessageBox::about(this,tr("提示"),tr("HEX数据格式错误,\n数据形式类似:30 34 56"));
        }
    }
    else{
        if( ui->rdbUtf8->isChecked() )
        {
            serial->write( ui->teSend->toPlainText().toUtf8()   );
        }else
        {
            QByteArray arrutf8 =ui->teSend->toPlainText().toLocal8Bit();
            serial->write( Utf8ToGbk(arrutf8)   );
        }
    }
}
 
//串口接收处理
void MainWindow::serialReadData()
{
   //注意,直接append会从下一行开始,所以先放入QString
    QByteArray buf = serial->readAll();
    if(!buf.isEmpty())
    {
        QString txt = ui->teReceive->toPlainText();
 
        if( ui->ckbReceivehex->isChecked() )
        {
            ui->teReceive->append( QString( buf.toHex(' ') ) );
        }
        else
        {
            QTextCodec::ConverterState state;
            QTextCodec *codec = QTextCodec::codecForName("UTF-8");
            QString str = codec->toUnicode( buf.constData(), buf.size(), &state);
            if ( state.invalidChars )
            {
               str = QTextCodec::codecForName( "GBK" )->toUnicode(buf);
            }
            else
            {
               str =  codec->toUnicode(buf);
            }
            ui->teReceive->clear();
            ui->teReceive->append(  txt+str  );
        }
    }
 
}
 
void MainWindow::on_btnClearReceive_clicked()
{
    ui->teReceive->clear();
}
 
void MainWindow::on_btnClearSend_clicked()
{
    ui->teSend->clear();
}
 
void MainWindow::on_btnFind_clicked()
{
    ui->btnFind->setEnabled(false);
    findSerialPort();
    ui->btnFind->setEnabled(true);
}

4.效果

测试可以发送和接收GK/UTF8编码的数据。下图是和ATK-XCOM通过虚拟串口交互。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Qt串口通信开发之QSerialPort模块Qt串口通信接收数据不完整的解决方法

    在使用串口接收数据时,当数据量大的时候会出现数据接收不完整的情况. 因为串口数据获取函数readAll()由readyRead()信号触发,但readyRead()信号在串口读到起始标志时立即发送,并不保证一定是当前所发数据的起始部分. 因此串口通信双方在通信前应制定好通信协议,规定好数据的起始和结束标志,串口当读到完整的起始和结束标志之后,才认定读完一条完整的数据. 本例中用串口定时发送当前时间,用"#"表示数据的结尾,定时时间为0毫秒,即能发多快就发多快. 发送 void Widg

  • QT串口通信的实现方法

    前言:如果用qt写程序作为上位机,然后通过和usb和下位机通信的时候,就需要用到qt中的串口通信了. 使用qt中的串口通信的时候需要用到的两个头文件分别为: #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> 除了加上面两个头文件之外,还需要在工程文件中加下面一行代码: QT += serialport 我们一般都需要先定义一个全局的串口对象,记得在自己的头文件中添加上: QSeri

  • Qt串口通信开发之QSerialPort模块详细使用方法与实例

    Qt串口通信基础及名词说明 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据.它很简单并且能够实现远距离通信.比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米: 而对于串口而言,长度可达1200米.典型地,串口用于ASCII码字符的传输.通信使用3根线完成,分别是地线.发送.接收.由于串口通信

  • Qt串口通信开发之Qt串口通信模块QSerialPort开发完整实例(串口助手开发)

    之前自己写了用于上位机做基本收发的界面,独立出来相当于一个串口助手,先贴图: 功能作为串口助手来说还算完善,五个发送槽,一个接收槽,可以检测可用串口并加上相关标志,串口设置,记数功能,还有菜单栏上的文件操作和一些选择功能. 下面说一说这个项目: 做这个串口助手分为两步,第一步是设计界面,第二部是功能的代码实现. 一.界面设计 界面设计用Qt Designer,当然用Qt Creator的界面编辑器也可以,只不过感觉Qt Designer更好用一点,因为可以随时运行查看你的界面效果而不用编译整个项

  • Qt串口通信开发之QSerialPort模块简单使用方法与实例

    我这里主要是对串口类的简单使用,实现的功能是以读写方式打开串口,点击发送数据按钮将发送区的数据发送到缓冲区,然后在接收区显示出来,界面如下:(源码可以在这里下载) 这里使用了QSerialPort模块提供的两个类:QSerialPort类和QSerialPortInfo类,QSerialPort类提供了对串口的操作,QSerialPortInfo类提供了对串口信息的获取.下面是主要代码,包含了对串口类的简单使用. 首先,一定要在.pro文件中添加:QT += serialport 串口初始化如下

  • Qt5 串口类QSerialPort的实现

    目录 简述 1.QSerialPortInfo类 2.QSerialPort类 简述 在Qt5以上提供了QtSerialPort模块,方便编程人员快速的开发应用串口的应用程序. QtSerialPort模块中提供了两个C++类,分别是QSerialPort 和QSerialPortInfo. QSerialPort 类是Qt5封装的串口类,可与串口进行通信,提供了操作串口的各种接口. QSerialPortInfo类是一个辅助类,可以提供计算机中可用串口的各种信息.如可用的串口名称,描述,制造商

  • Qt实现串口助手

    本文实例为大家分享了Qt实现串口助手的具体代码,供大家参考,具体内容如下 1.界面布局 这是一个常见的串口助手布局.要说有什么不常见,大概就是发送可以选择编码方式:GBK/UTF8 2.要点 没什么难度,就是水磨工夫,一点点写.容易错处的地方都写在代码注释里. 3.代码 下面是 mainwindow.cpp 文件. #include "mainwindow.h" #include "ui_mainwindow.h" #include <qdebug.h>

  • 5分钟用C#实现串口助手

    目录 第一步,创建新项目,选择Windows窗体应用 第二步,点击工具箱,拖拽控件,搭建一下页面 第三步,拖入serial port控件,并添加回调函数 第四步,实现按钮功能 非常简单的扩展框架 嵌入式开发中,由于产品的绑定.验证等逻辑限制比较严重,需要自己做一个上位机工具,来实现USB/BT通讯工具,实现如串口通讯.OTA升级等功能. 开发之初,比较了下C#和QT的环境,还是C#在window环境下开发更为简单,qt往往还需要自己解决Windows环境配置问题. 第一步,创建新项目,选择Win

  • 对python3 Serial 串口助手的接收读取数据方法详解

    其实网上已经有许多python语言书写的串口,但大部分都是python2写的,没有找到一个合适的python编写的串口助手,只能自己来写一个串口助手,由于我只需要串口能够接收读取数据就可以了,故而这个串口助手只实现了数据的接收读取. 创建串口助手首先需要创建一个类,重构类的实现过程如下: #coding=gb18030 import threading import time import serial class ComThread: def __init__(self, Port='COM3

  • python实战串口助手_解决8串口多个发送的问题

    今晚终于解决了串口发送的问题,更改代码如下: def write(self, data): if self.alive: if self.serSer.isOpen(): self.serSer.write(data) def m_send1butOnButtonClick( self, event ): if self.ser.alive: send_data = '' send_data += str(self.m_textCtrl5.GetValue()) self.ser.write(s

  • C# 实现简易的串口监视上位机功能附源码下载

    实现上位机和下位机之间的通信,通常使用的是串口通信,接下来实现一个通过上位机和串口调试助手来完成串口通信测试. 首先创建一个WInfrom窗体应用工程文件,创建过程可参考  https://www.jb51.net/article/150973.htm 在创建好的工程下面,通过工具箱中已有的控件完成界面的搭建,如下图所示,为了方便初学者容易看懂程序,下图将控件的命名一并标注出来: 直接进入正题,将完整的工程代码黏贴出来: using System; using System.Collection

  • C#串口通信工具类的封装

    本文实例为大家分享了C#串口通信工具类的封装代码,供大家参考,具体内容如下  1.SerialPortHelper串口工具类封装 using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Timers;   namespace public.Util {

  • Android提高之Android手机与BLE终端通信

    最近穿戴设备发展得很火,把相关技术也带旺了,其中一项是BLE(Bluetooth Low Energy).BLE是蓝牙4.0的核心Profile,主打功能是快速搜索,快速连接,超低功耗保持连接和传输数据,弱点是数据传输速率低,由于BLE的低功耗特点,因此普遍用于穿戴设备.Android 4.3才开始支持BLE API,所以请各位客官把本文代码运行在蓝牙4.0和Android 4.3及其以上的系统,另外本文所用的BLE终端是一个蓝牙4.0的串口蓝牙模块. 注:笔者的i9100刷了4.4系统后,竟然

  • C语言实现电脑关机程序

    本文实例为大家分享了C语言实现电脑关机的具体代码,供大家参考,具体内容如下 这个是我在网上搜索到的资料,其实也是很简单的. 想使用ESP8266完成这样一个操作--远程关闭电脑,达到人在别的任何地方都可以操作我们的电脑. 这个虽然已经不是羡慕新奇的事,实现的方法也撑出不穷,但我们学习ESP8266,也不失是一种体验的过程. 对于初学者来说也是一种很有成就感的体验. 因此,想完成远程关机,就需要理解怎么实现关机的命令及程序,我们使用C语言来完成. 串口助手也可以实现,但串口助手毕竟是为了调式用的,

随机推荐