基于QT的串口调试助手

Posted KookNut39

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于QT的串口调试助手相关的知识,希望对你有一定的参考价值。

大家好,我是KookNut39,在CSDN写文,分享一些自己认为在学习过程中比较重要的东西,致力于帮助初学者入门,希望可以帮助你进步。最近在更新C/C++方面的知识,感兴趣的欢迎关注博主,可以去专栏查看之前的文章,希望未来能和大家共同探讨技术。

由于某项目需要,需要写一个处理串口数据的程序,之前也没有用过Qt,所以这次打算用Qt实现这个功能。

有一说一,Qt相比于MFC真的是方便快捷了很多,在开发界面的方面还是很强大的。
话不多说,先上咱们最终实现的效果图。界面简单,如果大家在某些地方需要通过串口获取数据之后做处理的话,可以考虑使用。
通过点击按钮从串口读取数据并展现到文本框中。

功能是能够实现获取串口数据最简单的一些基础功能,肯定是不能和网上下载的很多成熟的软件比较,就比如微软自带的串口调试助手,如下图:
除了能够实现读取数据的同时,还能够设置额外输出方式等等算是额外辅助的功能吧。

实现的步骤按照如下几个步骤展开讲解:
对于串口的读取,Qt中自带了两个类供我们使用,分别是QtSerialPort、QserialPortInfo,基础对串口的操作这两个类都是提供了的。兄弟们如果在这个基础上加功能可以查询一下这两个类,根据这两个类里面自带的函数扩充你想要的功能。

1、首先就是在.pro文件中加上serialport,熟悉Qt的小伙伴一定都知道在Qt中使用什么额外的功能呀什么的,就要在这个部分写上这句话。

QT       += core gui serialport

2、对界面上的一些空间初始化
对于界面中控件的一些命名什么的,大家可以看下面的代码,通过变量名大家可以很容易得到控件的命名信息。这里就不详细给兄弟们展示了。

	//设置串口初始化状态
    ReadSerialPort = NULL;
    //设置界面初始的状态
    ui->ReadBtn->setEnabled(true);
    ui->StopReadBtn->setEnabled(false);
    //初始化串口设置部分
    ui->ChooseComComboBox->clear();
    ui->ChooseBoudComboBox->clear();
    ui->ChooseDataBitsComboBox->clear();
    ui->ChooseParityComboBox->clear();
    ui->ChooseStopComboBox->clear();
    QStringList ChooseComList;
    QStringList ChooseBoudList;
    QStringList ChooseDataBitsList;
    QStringList ChooseParityList;
    QStringList ChooseStopList;
    //获取电脑连接的串口信息供选择
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        ChooseComList << info.portName();
    }
    ui->ChooseComComboBox->addItems(ChooseComList);
    ui->ChooseComComboBox->setCurrentIndex(0);
    //波特率的选择
    ChooseBoudList <<"1200" <<"2400" <<"4800" <<"9600" <<"19200" <<"38400" <<"57600" <<"115200";
    ui->ChooseBoudComboBox->addItems(ChooseBoudList);
    ui->ChooseBoudComboBox->setCurrentIndex(0);
    //数据位的选择
    ChooseDataBitsList <<"5" <<"6"<<"7"<<"8"<<"UnknownDataBits";
    ui->ChooseDataBitsComboBox->addItems(ChooseDataBitsList);
    ui->ChooseDataBitsComboBox->setCurrentIndex(0);
    //校验位的选择
    ChooseParityList <<"NoParity" <<"EvenParity" <<"OddParity" <<"UnknownParity";
    ui->ChooseParityComboBox->addItems(ChooseParityList);
    ui->ChooseParityComboBox->setCurrentIndex(0);
    //停止位的选择
    ChooseStopList  <<"1" <<"2" <<"无";
    ui->ChooseStopComboBox->addItems(ChooseStopList);
	ui->ChooseStopComboBox->setCurrentIndex(0);

3、连接串口功能的实现。这也是最核心的部分:

	//点击按钮之后把状态改变了
    ui->ReadBtn->setEnabled(false);
    ui->StopReadBtn->setEnabled(true);
    //每次点击按钮之后创建一个对象,这也是解决了之前读取空值的问题
    ReadSerialPort = new QSerialPort();
    if(ReadSerialPort->isOpen())//如果串口已经打开了 先给他关闭了
    {
        ReadSerialPort->clear();
        ReadSerialPort->close();
    }
    //根据下拉框选取串口
    QString ChoosedPortName=ui->ChooseComComboBox->currentText();
    ReadSerialPort->setPortName(ChoosedPortName);//当前选择的串口名字

    if(ReadSerialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
    {
        ReadSerialPort->setDataTerminalReady(true);
        //根据下拉框选择波特率
        qint32 BaudrateIndex = ui->ChooseBoudComboBox->currentIndex();
        switch (BaudrateIndex) {
        case 0:
            ReadSerialPort->setBaudRate(QSerialPort::Baud1200);
            break;
        case 1:
            ReadSerialPort->setBaudRate(QSerialPort::Baud2400);
            break;
        case 2:
            ReadSerialPort->setBaudRate(QSerialPort::Baud4800);
            break;
        case 3:
            ReadSerialPort->setBaudRate(QSerialPort::Baud9600);
            break;
        case 4:
            ReadSerialPort->setBaudRate(QSerialPort::Baud19200);
            break;
        case 5:
            ReadSerialPort->setBaudRate(QSerialPort::Baud38400);
            break;
        case 6:
            ReadSerialPort->setBaudRate(QSerialPort::Baud57600);
            break;
        case 7:
            ReadSerialPort->setBaudRate(QSerialPort::Baud115200);
            break;
        default:
            ReadSerialPort->setBaudRate(QSerialPort::UnknownBaud);
            break;
        }
        //根据下拉框选择数据位
        qint32 DatabitsIndex=ui->ChooseDataBitsComboBox->currentIndex();
        switch (DatabitsIndex) {
        case 0:
            ReadSerialPort->setDataBits(QSerialPort::Data5);
            break;
        case 1:
            ReadSerialPort->setDataBits(QSerialPort::Data6);
            break;
        case 2:
            ReadSerialPort->setDataBits(QSerialPort::Data7);
            break;
        case 3:
            ReadSerialPort->setDataBits(QSerialPort::Data8);
            break;
        default:
            ReadSerialPort->setDataBits(QSerialPort::UnknownDataBits);
            break;
        }
        //根据下拉框选择校验位
        qint32 ParityIndex=ui->ChooseParityComboBox->currentIndex();
        switch (ParityIndex) {
        case 0:
            ReadSerialPort->setParity(QSerialPort::NoParity);
            break;
        case 1:
            ReadSerialPort->setParity(QSerialPort::EvenParity);
            break;
        case 2:
            ReadSerialPort->setParity(QSerialPort::OddParity);
            break;
        default:
            ReadSerialPort->setParity(QSerialPort::UnknownParity);
            break;
        }
        //根据下拉框选择停止位
        qint32 StopbitIndex=ui->ChooseStopComboBox->currentIndex();
        switch (StopbitIndex) {
        case 0:
            ReadSerialPort->setStopBits(QSerialPort::OneStop);
            break;
        case 1:
            ReadSerialPort->setStopBits(QSerialPort::TwoStop);
            break;
        default:
            ReadSerialPort->setStopBits(QSerialPort::UnknownStopBits);
            break;
        }
        //实例 误删
        //ReadSerialPort->setBaudRate(QSerialPort::Baud115200);//设置波特率和读写方向
        //ReadSerialPort->setDataBits(QSerialPort::Data8);		//数据位为8位
        //ReadSerialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
        //ReadSerialPort->setParity(QSerialPort::NoParity);	//奇校验位
        //ReadSerialPort->setStopBits(QSerialPort::OneStop); //两位停止位

        ReadSerialPort->clearError();
        ReadSerialPort->clear();

        connect(ReadSerialPort,&QSerialPort::readyRead,this,&Read::receiveInfo);

这里说一下之前自己遇到的一个问题吧,原本我的QT版本是5.13.0,当时代码已经调整过了,但是无论怎样都无法获取到串口传过来的值,这个bug改了整整一天,后来发现是QT这个版本的问题,后来把这个版本卸载然后装上了5.14.2,问题直接解决。
当然这里要提一下还有另外一个方式可以解决这个问题,就是通过添加waitForReadyRead(30000);这个方式倒是也解决了读取的问题,但是后面遇到了其他的的问题,可能是因为我当时想着使用线程的原因,导致的程序崩溃的问题,但是具体是不是因为这句话我就不知道了,但是换了版本之前的问题迎刃而解。我这里还是建议大家直接安装一个没有问题的版本吧,后面会省去很多的事情。

4、输出数据实现

void Read::receiveInfo()
{
    //读取串口的数据并且把数据转换成字符串类型
	QByteArray info = ReadSerialPort->readAll();
	qDebug() << info;
	ui->GpsOutputTextEdit->append(info);
}

以上是关于基于QT的串口调试助手的主要内容,如果未能解决你的问题,请参考以下文章

干货|手把手教你写一个串口调试助手

干货|手把手教你写一个串口调试助手

Python Qt GUI设计:做一款串口调试助手(实战篇—1)

QT应用编程: 编写HC05串口蓝牙调试助手(Android系统APP)

QT应用编程: 编写HC05串口蓝牙调试助手(Android系统APP)

基于QT的串口助手