摘要:相信很多小伙伴都没接触过QT,如果想用QT写一个调试助手,首先是要会一点C++语法。只要能看得懂C++的代码,就能很快的写一个串口调试助手。

下面先推荐两个视频教程,感兴趣的可以看一看!

1、B站Jomse工

B站Jomse工

看完你基本就知道串口调试助手大概是个啥样了,有了大致的了解,然后再去看和修改别人的代码。

2、B站lililanglang

B站lililanglang

把这两个视频看完后,基本你就能够自己写一个串口调试助手了,视频很短没有废话,全程都是干货,而且别人也给出了源码。

不过,为了大家方便理解,我还是写一篇手把手教你学QT串口调试助手吧!

3、新建工程

1、首先,你要安装QT的开发工具Qt Creator。安装过程这里就不再重复说了,大家可以看我的CSDN博客号前面发的一些文章,有介绍的。

然后,打开QtCreator新建一个项目:

项目名称根据需求自己指定即可,在指定项目的存储路径的时候,路径中不能包含中文,不能包含中文,不能包含中文。

直接写一步:

Class name可以随便写一个,一般默认不变。

Base nameQMainWindowQWidgetQDialog随便选一个即可。

编译套件用于项目文件的编译,如果安装了多个编译套件,在这里选择其中一个就可以了。

版本控制工具没有的话可以不选,主要用于团队开发,点击完成。

这样我们就新建好了一个项目工程!

双击ui文件即可进入设计模式,进入界面设计器Qt Designer编辑状态,开始进行设计器( Qt Designer )编程。

在这个界面,我们可以拖动左边的常用界面的空间到编辑窗口,然后生成可视化的界面。

样式1

样式2

可以看到,通过拖动控件与修改控件属性就可以做出上面这样的界面,我个人觉得还是非常的美观nice的。这里只是给大家一个参考的界面和模板,排版和配色大家按照自己喜欢的就可以了!

一、导入库

1、在项目.pro文件中加入serialport

QT       += core gui
QT       += serialport

2、引入qt中串口通信需要的头文件。

#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

二、配置串口初始化

1、查找可用的串口

通过创建一个comobox,将可用串口的列表展示出来,并用于配置时选择要连接的串口。

//查找可用串口,刷新串口信息
void MainWindow::GetAveriablePort()
{ui->uartReadPlain->insertPlainText("串口初始化:\r\n");//先清除所有串口列表ui->portBox->clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){QSerialPort serial;serial.setPort(info);if(serial.open(QIODevice::ReadWrite)){ui->uartReadPlain->insertPlainText("可用:"+serial.portName()+"\r\n");ui->portBox->addItem(serial.portName());serial.close();}else{ui->uartReadPlain->insertPlainText("不可用:"+serial.portName()+"\r\n");}}
}

2、配置串口

(1)串口的配置至少应当包含串口号、波特率、数据位、停止位、奇偶校验位、流控,这些都可以通过串口实例调用函数配置。可以加入几个comobox或者文本框来选择,也可以默认初始化时就配好。

//配置串口初始化
void MainWindow::PortConfigureInit()
{//填入串口选项ui->rateBox->addItem("115200","115200");ui->rateBox->addItem("38400","38400");ui->rateBox->addItem("19200","19200");ui->rateBox->addItem("9600","9600");ui->dataBox->addItem("8",8);ui->dataBox->addItem("7",7);ui->checkBox->addItem("无校验",0);ui->stopBox->addItem("1位",1);ui->stopBox->addItem("2位",2);
}

(2)加入一个打开关闭串口的按钮,文本显示“打开串口”时,点击可以关闭串口。文本显示“关闭串口“则相反。

(3)打开串口时,把配置的项的box都disable,使其不可修改,关闭时恢复。

//串口开关按钮
void MainWindow::on_openSerialButton_clicked()
{//尝试打开串口if(ui->openSerialButton->text() == tr("打开串口")){if(ui->portBox->currentText() == "" ){QMessageBox::warning(NULL, "警告", "无可开启串口!\r\n\r\n");return;}serial = new QSerialPort;//设置串口名serial->setPortName(ui->portBox->currentText());//打开串口serial->open(QIODevice::ReadWrite);//设置波特率serial->setBaudRate(ui->rateBox->currentText().toInt());//设置数据位switch (ui->dataBox->currentData().toInt()){case 8:serial->setDataBits(QSerialPort::Data8);break;case 7:serial->setDataBits(QSerialPort::Data7);break;default:break;}//设置校验位switch (ui->checkBox->currentIndex()){case 0:serial->setParity(QSerialPort::NoParity);break;default:break;}//设置停止位switch(ui->stopBox->currentIndex()){case 0:serial->setStopBits(QSerialPort::OneStop);break;case 1:serial->setStopBits(QSerialPort::TwoStop);break;default:break;}//设置流控制serial->setFlowControl(QSerialPort::NoFlowControl); //设置为无流控制//关闭设置菜单使能ui->portBox->setEnabled(false);ui->dataBox->setEnabled(false);ui->checkBox->setEnabled(false);ui->stopBox->setEnabled(false);ui->rateBox->setEnabled(false);ui->openSerialButton->setText("关闭串口");fTimeCounter.restart();  //计时器重新计数//连接信号和槽函数,串口有数据可读时,调用ReadData()函数读取数据并处理。QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);}else{uartRecDataTimer->stop () ; //定时器停止if(serial->isOpen())       //原先串口打开,则关闭串口{serial->close();}//释放串口delete serial;serial = NULL;//恢复使能ui->portBox->setEnabled(true);ui->rateBox->setEnabled(true);ui->dataBox->setEnabled(true);ui->checkBox->setEnabled(true);ui->stopBox->setEnabled(true);ui->openSerialButton->setText("打开串口");}
}

三、读取串口数据

1、为了读取数据,要创建一个定时器和一个计时器。因为要解决两个问题:

一是我们需要一个超时间隔,用于在串口一定时间收不到数据时,判断一次接收完成,处理数据并清空buff

二是需要一个计数,统计串口已经连续接收了多久,即使数据一直不断,我们也要在一个固定时时间点强制判断一次接收完成,处理数据并清空buff,否则可能会导致数据永远得不到处理。

1、初始化定时器

    //设置uart接收缓冲超时定时器uartRecDataTimer = new QTimer(this);uartRecDataTimer->stop();uartRecDataTimer->setInterval(uartRecOvertimeCount*1000);                     //设置定时周期,单位:毫秒uartRecDataTimer->setSingleShot(true);                                        //设置为单次触发connect(uartRecDataTimer,SIGNAL(timeout()),this,SLOT(uartRec_timeout()));     //设置槽

2、实现ReadData

在计时器超出一个指定间隔后,强制处理已经接收完的buff缓冲,其余时间则是把数据放进缓冲中,重启定时器。

//读取串口接收消息
void MainWindow::ReadData()
{//串口可读数据长度int byteLen = serial->bytesAvailable();if(byteLen < 0){return;}rec_buf_len += byteLen;uart_rec_ss.append(serial->readAll());  //读取数据//计时器超过最大间隔仍未填入数据,强制填入if(fTimeCounter.elapsed() >2000 && uart_rec_ss.size()>0){ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾ui->uartReadPlain->insertPlainText(uart_rec_ss);ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾uart_rec_ss.clear();}//定时器开始工作、定时器重启uartRecDataTimer->start();
}

3、数据内容做填充

定时器接收完成处理(一段时间没有数据接收,定时器超时)根据时间戳是否被选择,将数据内容做填充,插入到存放数据的文本框里。

//定时器触发打印串口数据
void MainWindow::uartRec_timeout()
{if(!uart_rec_ss.isEmpty()){curDateTime = QDateTime::currentDateTime();ui->uartReadPlain->moveCursor(QTextCursor::End);            //光标移动到结尾if(ui->timeZoneCheckBox->isChecked()){ui->uartReadPlain->insertPlainText("\r\n"+curDateTime.toString("[yyyy-MM-dd hh:mm:ss]")+"R:");ui->uartReadPlain->moveCursor(QTextCursor::End);        //光标移动到结尾ui->uartReadPlain->insertPlainText(uart_rec_ss);}else{ui->uartReadPlain->insertPlainText(uart_rec_ss);}ui->uartReadPlain->moveCursor(QTextCursor::End);            //光标移动到结尾uart_rec_ss.clear();fTimeCounter.restart();ui->RXLenLabel->setText(QString::number(rec_buf_len)+"bytes");}
}

4、配置超时间隔的选项

(1)初始化时加入一个配置框

//设置时间输入框只允许使用数字
ui->overTimeRecEdit->setValidator(new QRegExpValidator(QRegExp("^([0-9]{1,4}(.[0-9]{1,3})?)$")));
ui->overTimeRecEdit->setText(QString::number(uartRecOvertimeCount));

(2)运行中配置超时间隔

//超时间隔设置
void MainWindow::on_overTimeRecEdit_returnPressed()
{if(ui->overTimeRecEdit->text().toFloat()>60){QMessageBox::warning(NULL,"警告","超时时间不要超过1分钟");ui->overTimeRecEdit->setText("0.1");return;}uartRecOvertimeCount = ui->overTimeRecEdit->text().toFloat();ui->uartReadPlain->insertPlainText("设置超时时间为:"+QString::number(uartRecOvertimeCount*1000)+"ms");uartRecDataTimer->setInterval(uartRecOvertimeCount*1000);                       //设置定时周期,单位:毫秒fTimeCounter.restart();uartRecDataTimer->start();
}

四、发送数据

简单的发送数据没有什么要额外配置的,调用write函数就可以了,可以根据自己的实际情况做一些配置或是校验处理,比如加回车换行什么的。

//发送串口数据
void MainWindow::on_sendDataButton_clicked()
{//未打开串口则不准发送if(ui->openSerialButton->text() == "打开串口"){QMessageBox::warning(NULL, "警告", "未打开可用串口,无法发送数据!\r\n\r\n");return;} //获取发送的命令,并选择在结尾加上换行,AT的命令结尾必须有回车换行QString command = ui->uartWritePlain->toPlainText();if(ui->changeLineCheckBox->isChecked()){command += "\r\n";} if(ui->timeZoneCheckBox->isChecked()){curDateTime = QDateTime::currentDateTime();ui->uartReadPlain->insertPlainText("\r\n"+curDateTime.toString("[yyyy-MM-dd hh:mm:ss]")+"SEND:"+command);} send_buf_len += command.length();ui->TXLenLabel->setText(QString::number(send_buf_len)+"bytes"); serial->write(command.toLatin1());
}

至此,一个最基本的串口调试工具就完成了,下面就是给它添加功能和优化了。你可以加入一些功能比如修改样式、保存数据等等。

开源代码

最后想说的是,用QT写上位机的源码例程很多,初学者可以先借鉴别人的代码参考修改,按照自己的喜好以及编程风格进行排版和布局配色即可!

从零开始,教你写一个串口调试助手相关推荐

  1. 手把手教你写一个串口调试助手

    硬件攻城狮 2022-05-20 14:05 发表于广东 果果小师弟. 电子信息工程硕士在读,分享单片机.嵌入式linux.物联网等知识,致力于打造最硬核的嵌入式技术公众号. 摘要:前段时间发布了一个 ...

  2. 自己写了一个串口调试助手

    五叶草串口调试助手(持续更新-) 最新版本v1.1.0.0 介绍 作为一个嵌入式开发者, 经常用到串口, 也经常因为串口调试助手而烦恼. 于是决定自己做一款串口调试助手. 修改日志 v1.1.0.0 ...

  3. 学习笔记:使用Qt制作一个串口调试助手

    界面设计参考了野火串口调试助手C#版 功能基本实现!实现效果看图: 第一步:制作图形界面 注意控件命名要又辨识度,不然在编写代码时将是很很痛苦的 第二步:添加相应的库 添加此次工程所需要的串口库,在工 ...

  4. 分享自己使用python+pyserial+pyQT5写的串口调试助手

    1.先介绍一下软件的运行环境,python3.6.1(32位) ,pyinstaller 3.3版本, pyserial 3.4版本, pyqt5 5.8.2版本,这些是主要用到的软件包.  在win ...

  5. C# WinForm 编写串口调试助手

    用C# 编写一个串口调试助手,这里借鉴学习了B站杜洋工作室的学习视频,现将代码拿出来分享学习, using System; using System.Collections.Generic; usin ...

  6. Qt实践录:串口调试助手

    由于项目需要使用到串口调试及测试,为了练手,使用 Qt 编写一个串口调试助手.本文按开发的过程进行简单介绍,同时也涉及部分用到的模块代码.详细代码参考源码仓库. 工具特性 具体功能 具备串口收发功能. ...

  7. 【搬家】VB.NET开发全功能串口调试助手

    VB.NET开发全功能串口调试助手 By Nightmare 2011-07-16 @Xinxiang 小记:VB.NET的串口通信用了很长时间了,也只用Write和Read这样的方法,以前都是用这种 ...

  8. 【分享】vofa+串口调试助手

    前言 今天看到一个网友推荐了一个串口调试助手"vofa+": 因为我目前使用的串口调试助手都不太满意,像: "sscom5.13.1" 是非常好用,但是功能太少 ...

  9. 多功能串口调试助手XUTOPIA

    多功能串口调试助手XUTOPIA 利用C#基于WPF开发的多功能串口调试助手 概述 在嵌入式开发的过程中,由于经常需要下位机与上位机通信,下位机与上位机之间的通信大多都是串口通信,网上大多数串口调试助 ...

最新文章

  1. 【合并单元格】纵向合并单元格之前对数组处理【针对饿了么element的table的span-method合并行或列的计算方法】
  2. ajax里绑定框,Select级联菜单,用Ajax获取Json绑定下拉框(jQuery)
  3. 802.11 n wlan linux驱动下载,802.11n无线网卡驱动
  4. 超详细的Hadoop2配置详解
  5. gcc2.95.3安装过程
  6. Ubuntu环境下sublime3 nodejs安装与插件配置
  7. 苹果无人车四个最新专利:手势控制变道、车辆导流、路况感知及车辆控制
  8. YOLO V5 实现课堂行为检测
  9. 电机驱动电路中的Snubber网络设计
  10. 学习OpenCV3 面阵相机标定方法
  11. 2021秋软工实践个人作业一
  12. sql注入bypass方法
  13. swift开发之pop动画
  14. Win7系统设置共享打印机出现0x000006d9错误怎么办?
  15. python中的isdigit()函数
  16. 修改MAC访达备份iphone到外设
  17. 《游戏引擎架构》读书笔记(四)
  18. 上线五个多月,Temu遭受太多非议?
  19. 基于stm32f4外部输入上升沿或下降沿的采集处理
  20. 读《我的管理哲学 - 任正非》

热门文章

  1. 图形 2.4 传统经验光照模型详解
  2. Linux操作系统下的常用基本指令(实用加收藏)
  3. JavaWeb(Web概念、HTML)
  4. 2021年5月-国家注册审核员-《认证通用基础》真题10-解析版
  5. 关于高速计数指令PRV直读不到脉冲计数
  6. Qt Quik是什么?
  7. 用C/C++实现简单游戏开发:easyx实现幻彩贪吃蛇
  8. 路由器RIP动态路由配置
  9. 帆软单点登录_FineReport和泛微OA(Ecology)的单点登录集成方案
  10. Biotin hydrazide,Biotin hydrazide HCl 一种酰肼活化的生物素化试剂