串口调试工具开发

2023-05-16

刚学习Qt,搜查资料,根据学到的知识,完成一个简单的串口调试工具~刚入行,谅解

最终效果图,图上功能都可实现

UI界面绘制:

代码如下:

串口调试工具开发

1.创建工程QWidget,根据串口调试工具绘制Ui界面
给每个控件设置特定名,方便调用

2.在.pro文件添加代码
QT  += core gui serialport

3.在.h文件头添加代码
#include <QSerialPort>
#include <QSerialPortInfo>

private:
    Ui::Widget *ui;
    QSerialPort * serialport;//串口端口
    QTimer *timSend;//创建定时器对象
    QString  mTime;//拼接日志样式对象
    QDateTime mDateTime;//获取当前时间
    QByteArray Sendtext;//发送缓存区
    QByteArray Receivetext;//接收缓存区
    long int SendByte=0;//发送字符数
    long int ReceByte=0;//接收字符数

4.给串口号设置自动获取电脑中的串口

//遍历可用串口设备
    //创建一个QStringList 对象来存储端口名
    QStringList serialPort_Name;
    //foreach遍历方法
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){
        //端口名呈现格式
        serialPort_Name << info.portName();
    }
    //添加到控件串口显示
    ui->PostName->addItems(serialPort_Name);

*如果需要过滤无用串口,代码如下

//获取串口列表
        int snum=0;
        
        //用下面的方法会过滤掉一些无用的串口
        QSerialPort temp_serial;
        foreach (const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {

            temp_serial.setPort(Info);
            if(temp_serial.open(QIODevice::ReadWrite)){//如果串口是可以读写方式打开的
                ui->PostName->addItem(Info.portName());
                temp_serial.close();
                ++snum;
            }
        }
        //默认选中第0项
        if(snum>2){
            ui->PostName->setCurrentIndex(1);
        }
         ui->PostName->currentText();

*如果需要对下拉框进行自适应设置,代码如下

//下拉列表自适应
    /* 获取最长字符串 */
    int maxlen = 0;
    for (int index = 0; index < ui->PostName->count(); index++)
    {
        if (ui->PostName->itemText(index).length() > maxlen)
        {
            maxlen = ui->PostName->itemText(index).length();
        }
    }
    /*获取字体磅值转换为像素值*/
    int fontsize = ui->PostName->font().pointSize();//获取字体的磅值
    ui->PostName->setFixedWidth(fontsize * maxlen * 0.75);//设置像素值
```

接下来需声明一个串口全局对象,在.h文件中
QSerialPort * serialport;//串口端口


声明后在.cpp文件中创建出来
serialport = new QSerialPort(this);//声明后把对象创建出来

给打开按钮设置转到槽

.h文件自动生成
private slots:
    void on_Btn_Open_clicked();//打开键按下

/*打开按钮配置*/
/*串口参数配置*/
void Widget::on_Btn_Open_clicked()
{
    if (ui->Btn_Open->text()=="打开") {
        //设置串口名
        serialport->setPortName(ui->PostName->currentText());
        //设置波特率
        switch (ui->BaudRate->currentIndex())
        {
        case 0:
            serialport->setBaudRate(QSerialPort::Baud19200,QSerialPort::AllDirections);
            break;

        case 1:
            serialport->setBaudRate(QSerialPort::Baud38400,QSerialPort::AllDirections);
            break;
        case 2:
            serialport->setBaudRate(QSerialPort::Baud57600,QSerialPort::AllDirections);
            break;
        default:
            serialport->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
            break;
        }
/* 检验位、数据位、停止位、流控制 与 波特率(switch)写法一致 */
        
        //打开串口
        if(!serialport->open(QIODevice::ReadWrite)){
            QMessageBox::about(NULL,"提示","无法打开串口");
            return;
        }
        
        /*点击后效果*/
        //设置控件不可编辑
        ui->PostName->setEnabled(false);
        ui->BaudRate->setEnabled(false);
        ui->Parity->setEnabled(false);
        ui->DataBits->setEnabled(false);
        ui->StopBits->setEnabled(false);
        ui->FlowControl->setEnabled(false);
        //点击打开按钮后发送和循环发送可编辑
        ui->Btn_Send->setEnabled(true);
        ui->Cyclet_time->setEnabled(true);
        //点击打开后显示关闭
        ui->Btn_Open->setText("关闭");
        ui->Btn_Open->setStyleSheet("QPushButton{color:red;background:yellow}");
        
        /*点击前效果*/
        与上方代码相反,写在else{}中
```

获取时间戳

/*获取时间戳*/
先在.h头文件创建对象,如经常使用的对象,都在头文件创建,减少损耗资源
QString  mTime;
QDateTime mDateTime;
.cpp文件写对应事件
if(ui->Re_Log->isChecked()){
        mDateTime = QDateTime::currentDateTime();
    //拼接日志样式
        mTime = "[";
        mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;
        mTime += "]:RECV ->" ;
        mTime += Receivetext;
        ui->Re_Edit->append(mTime);
    }

添加数据换行问题,insertPlainText函数在原数据末尾直接添加,可以使用append函数替代换行添加

if(ui->Re_Line->checkState()==Qt::Checked)
    {
        ui->Re_Edit->append(Receivetext);
    }
    else
    {
        ui->Re_Edit->insertPlainText(Receivetext);
    }
```

**串口接收代码**

/*串口接收*/
void Widget::on_SerialPort_readyRead(){
    int i,length;
    Receivetext = serialport->readAll();

    //接收字节并显示
    ReceByte+=Receivetext.length();
    ui->Re_Byte->setText(QString::number(ReceByte));

    //十六进制
    if(ui->Re_Hex->checkState()==Qt::Checked)
    {
        //字符串转十六进制
        Receivetext = Receivetext.toHex().toUpper();
        length=Receivetext.length();
        for(i=0;i<=length/2;i++)
        {
            //插入空格字符串
            Receivetext.insert((2+3*i),' ');
        }
    }

    //自动换行
    if(ui->Re_Line->checkState()==Qt::Checked)
    {
        ui->Re_Edit->append(Receivetext);
    }
    //日志显示样式
    else if(ui->Re_Log->isChecked()){
        //获取当前时间
        mDateTime = QDateTime::currentDateTime();
        //时间展示拼接样式
        mTime = "[";
        mTime += mDateTime.toString("[yyyy-MM-dd hh:mm:ss.zzz]") ;
        mTime += "]:RECV ->" ;
        mTime += Receivetext;
        //append自动换行
        ui->Re_Edit->append(mTime);
    }
    else
    {
        //原数据末尾添加(文本接收)
        ui->Re_Edit->insertPlainText(Receivetext);
    }
}

**串口发送代码**

void Widget::on_Btn_Send_clicked()
{
    int i,length;
    Sendtext = ui->Se_Edit->toPlainText().toUtf8();

    //发送设置HEX
    if(ui->Se_Hex->checkState()==Qt::Checked)
    {
        //转换成十六进制
        Sendtext = Sendtext.toHex().toUpper();
        length=Sendtext.length();
        for(i=0;i<=length/2;i++)
        {
            //插入空格字符串
            Sendtext.insert((2+3*i),' ');
        }

        serialport->write(Sendtext);
    }
    else
    {
        serialport->write(Sendtext);

    }
    //发送字节显示
    SendByte+=Sendtext.length();
    ui->Se_Byte->setText(QString::number(SendByte));
//    ui->Se_Edit->moveCursor(QTextCursor::End);

}


定时器使用方法

在.h头文件中
//定义并初始化mTimerID
int  mTimerID= 0;
    
  /*定时器定时发送*/
    //设置默认值1000ms
mTimerID = startTimer(500);

在.cpp文件中
void Widget::timerEvent(QTimerEvent *event)
{
    qDebug()<<"我是定时器!";
}
void Widget::closeEvent(QCloseEvent *event)
{
    if(mTimerID)
    {
        killTimer(mTimerID);

        mTimerID = 0;
    }
}

**串口循环发送代码**

在.h头文件
QTimer *timSend;//创建定时器对象

在.cpp文件
//定时发送=定时器
       timSend=new QTimer;
       timSend->setInterval(1000);//设置默认值1000ms
        //定时器信号连接发送信号
        connect(timSend,&QTimer::timeout,this,[=]()
        {
           on_Btn_Send_clicked();
        });

ui界面给循环发送checkbox转到槽
    void on_Cyclet_time_stateChanged(int arg1);//循环发送

void Widget::on_Cyclet_time_stateChanged(int arg1)
{
    //获取复选框状态,没有选就为0,选择了就为2
        if(arg1==0)
        {
            timSend->stop();
        }
        else {
            //对输入的值大小的限制,小于10会弹出对话框提示
            if(ui->Se_Line_2->text().toInt()>=10)
            {
                timSend->start(ui->Se_Line_2->text().toInt());//设置时长,重新计数
            }
            else {
                ui->Cyclet_time->setCheckState(Qt::Unchecked);
                QMessageBox::information(this,"错误提示","定时发送最小间隔为10ms!");
            }
        }
}

```

清空按钮

在.h头文件
void on_Btn_Reclean_clicked();//清空接收区域
void on_Btn_Seclean_clicked();//清空发送区域

在.cpp文件
/*清空接收区域*/
void Widget::on_Btn_Reclean_clicked()
{
    ui->Re_Edit->clear();
}
/*清空发送区域*/
void Widget::on_Btn_Seclean_clicked()
{
    ui->Se_Edit->clear();
}

ASCII、HEX发送与接收

在.h头文件中
void on_Re_Hex_clicked();//点击十六进制接收
void on_Se_Ascll_clicked();//点击ASCII发送

在.cpp文件中
/*十六进制接收*/
void Widget::on_Re_Hex_clicked()
{
    ui->Re_Ascll->setCheckState(Qt::Unchecked);
    ui->Re_Hex->setCheckState(Qt::Checked);
}

/*ASCII发送*/
void Widget::on_Se_Ascll_clicked()
{
    ui->Se_Ascll->setCheckState(Qt::Checked);
    ui->Se_Hex->setCheckState(Qt::Unchecked);
}

复位计数

在.h头文件中
void on_Btn_Reset_clicked();//复位计数

在.cpp文件中
/*清除计数*/
void Widget::on_Btn_Reset_clicked()
{
    SendByte = 0;
    ReceByte = 0;
    ui->Re_Byte->setText(QString::number(ReceByte));
    ui->Se_Byte->setText(QString::number(SendByte));
}
```

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口调试工具开发 的相关文章

  • 6-12 二叉搜索树的操作集 (30 分)

    本题要求实现给定二叉搜索树的5种常用操作 函数接口定义 xff1a BinTree Insert BinTree BST ElementType X BinTree Delete BinTree BST ElementType X Posi
  • C++ CAS 操作

    C 43 43 中的 CAS 操作用于操作原子变量 xff0c 它是 atomic lt T gt 的成员函数 span class token macro property span class token directive hash
  • 习题6-6 使用函数输出一个整数的逆序数 (20 分)

    本题要求实现一个求整数的逆序数的简单函数 函数接口定义 xff1a int reverse int number 其中函数reverse须返回用户传入的整型number的逆序数 裁判测试程序样例 xff1a include lt stdio
  • 数据结构之各种常用结构体总结

    一 线性表 define MaxSize 100 表长度初始定义 typedef struct ElemType data MaxSize 或者指示动态分配数组的指针Elemtype data int length 数组最大容量和长度 Sq
  • 习题2.7 弹球距离 (15 分)

    设有一个球从高度为h米的地方落下 xff0c 碰到地面后又弹到高度为原来p倍的位置 xff0c 然后又落下 xff0c 再弹起 xff0c 再落下 请编写函数求初始高度为h的球下落后到基本停下来 xff08 高度小于给定阈值TOL xff0
  • 习题7-3 判断上三角矩阵 (15 分)

    上三角矩阵指主对角线以下的元素都为0的矩阵 xff1b 主对角线为从矩阵的左上角至右下角的连线 本题要求编写程序 xff0c 判断一个给定的方阵是否上三角矩阵 输入格式 xff1a 输入第一行给出一个正整数T xff0c 为待测矩阵的个数
  • python计算黑白图像像素值

    span class token function import span numpy as np span class token function import span cv2 span class token comment 读入图
  • python将文件夹中图像生成file list

    按行排列 xff0c 图像路径 span class token function import span os span class token function import span argparse span class token
  • Markdown插入图片 详细例子(本地图片,网络图片,base64) Windows

    网上一番搜索 xff0c 领略到基本所有回答 xff0c 都是一样的 xff0c 简简单单的介绍 而且 xff0c TMD xff0c 插入图片答案的本地路径 xff0c 都是回答的是Linux或Mac OS系统的路径 xff0c 诸如 x
  • Pixhawk学习笔记(2)——问题汇总

    1 遥控器校准时 xff0c 拨动摇杆 xff0c 上位机通道数据不变化 解决方法 xff1a PPM编码器上有一个跳线需短接 xff0c 短接后才可通过编码器对遥控器接收机供电 供电前PPM编码器模块上蓝灯快闪 xff0c 供电后变为慢闪
  • 在FPGA中使用Verilog实现I2C通信

    按照I2C标准的官方时序 可以看出时序看起来很简单 xff0c 不过它严格的按照时序要求来传送数据 xff0c 马虎不得的 xff0c 特别是起始和停止的条件 xff0c 起始必须要时钟线SCL为高电平时数据线SDA拉低 xff1b 而停止
  • Pixhawk学习笔记(5)——PX4FLOW光流传感器调试过程记录

    先使用qgc地面站查看光流图像及数据 xff0c 能看到不错的图像和波形 烧写官网固件后 xff0c 接入pixhawk飞控 xff0c 使用apm固件 xff0c 勾选启用光流 xff0c 超声波选用pix iic xff0c 在miss
  • 数据结构—布隆过滤器

    布隆过滤器可以快速地告诉你 xff1a 某个值一定不存在 xff0c 以及某个值可能存在 布隆过滤器是基于位图和哈希函数 xff08 如 xff0c MurmurHash xff09 来实现了 此处假设有两个哈希函数 hash 1 hash
  • PX4/Pixhawk---快速成为开发者(Windows)

    1 快速成为开发者入门教程 xff08 翻译 xff09 官方 1 1 编译环境 xff08 1 xff09 安装 MSysGIT 安装完成后 xff0c 配置GIT 安装注意 安装过程中除了下面一步外 xff0c 其他的步骤都采用默认安装
  • Cdence版图设计手册

    Cadence版图设计 工作站常用命令 一 在terminal窗口键入的基本命令 xff1a 1 ls xff1a 列出目录下所有文件 2 clear xff1a 清除terminal窗口里的内容 3 pwd xff1a 显示目前工作的目录
  • Pixhawk开发手册

    一 常见问题 xff1a 1 遥控器校准时 xff0c 拨动摇杆 xff0c 上位机通道数据不变化 解决方法 xff1a PPM编码器上有一个跳线需短接 xff0c 短接后才可通过编码器对遥控器接收机供电 供电前PPM编码器模块上蓝灯快闪
  • 浅谈四轴PID调试心得

    以下内容转自阿莫论坛 xff0c 写得很详细 xff0c 是调试大四轴的 小四轴调试也可参照着调 PID调试心得 本人不是自动化出身 xff0c 也没有受过专业训练 xff0c 都是自己摸索 xff0c 在这里浅述一下自己的PID参数整定心
  • rctimer二轴云台及云台控制板调试(Simple bgc 8位破解板)

    前段时间在鬼王家抢了rctimer的二轴云台和控制板 xff0c 感觉做工很精良 这几天有空了就调试下 整个过程比较容易 xff0c 首先要准备好usbisp烧写器 xff0c 和一根阶梯形的micro usb线 先刷bootloader
  • APM和PIX飞控日志分析入门贴

    我们在飞行中 xff0c 经常会碰到各种各样的问题 xff0c 经常有模友很纳闷 xff0c 为什么我的飞机会这样那样的问题 xff0c 为什么我的飞机会炸机 xff0c 各种问题得不到答案是一件非常不爽的问题 xff0c 在APM和PIX

随机推荐

  • 微电子及集成电路设计常用问题总结(考研面试向)

    mos管的沟道长度调制效应 xff1f 源极导致势垒下降 xff1f 衬底电流体效应 xff1f 衬底偏执效应 xff1f 速度饱和效应 xff1f 举例典型的trade off xff1f mos amp bjt的工作曲线 xff1f 加
  • YOLO详解

    转载自 xff1a https zhuanlan zhihu com p 25236464 从五个方面解读CVPR2016 目标检测论文YOLO Unified Real Time Object Detection 创新 核心思想 效果 改
  • 使用微信监管你的TF训练

    以TensorFlow的example中 xff0c 利用CNN处理MNIST的程序为例 xff0c 我们做了下面一点点小小的修改 1 xff0c 首先导入了itchat和threading两个包分别用于微信和县线程 xff08 因为要有一
  • 你应该知道的9篇深度学习论文(CNNs 理解)

    当时看到英文的博客 xff0c 本想翻译给感兴趣的同学们看看 xff0c 没想到已经有人翻译 xff0c 于是进行了转载 xff0c 留给自己和更多的人学习 xff0c 本文仅供参考 英文博客 xff1a https adeshpande3
  • JS笔记(==和===的介绍)

    61 61 和 61 61 61 介绍 61 61 关系运算符 等于 用于比较两个操作数是否相等的 相等为true xff0c 否则为false 61 不等于 61 61 61 xff1a 绝对等于 用于比较两个操作数是否相等的 相等为tr
  • 全国大学生电子设计竞赛B题感悟-优象光流篇

    今年是2019年电赛国赛年 xff0c 这本是是一个很好的机会冲击国家奖的 xff0c 但是由于个人视野太窄 xff0c 眼光不够长远而错失良机 今年测评结束的时候我就已经预感到了结果 xff0c 记得比赛前去提交作品的时候 xff0c 大
  • 滑模控制以及系统动力学与控制论(1)

    维基百科里是这样定义系统 System 的 System from Latin syst ma in turn from Greek syst ma is a set of entities real or abstract compris
  • 安装docker

    首先信任 Docker 的 GPG 公钥 sudo apt key adv keyserver hkp p80 pool sks keyservers net 80 recv keys 58118E89F3A912897C070ADBF76
  • 我的AI之路(39)--使用深度相机之小觅深度相机

    小觅深度相机的SDK代码在github上 小觅相机的支持库需要从这里https github com slightech MYNT EYE D SDK下载SDK源码后本地编译后再安装 xff0c Ubuntu上的步骤是 xff1a 1 如果
  • DeepSORT C++版的一个bug

    DeepSORT的官方python版实现是https github com nwojke deep sort xff0c C 43 43 版的DeepSORT中https github com shaoshengsong DeepSORT这
  • 使用sudo运行vncserver后导致Ubuntu循环登录进入不了桌面的问题原因及解决办法

    因需要多人同时登录到机器人的Ubuntu主机调试 xff0c 于是安装VNC xff0c 不记得N年以前怎么做的了 xff0c 于是按照网上某文说的先 xff1a sudo apt get install xfce4 插一句 xff1a 也
  • CAS6.1 配置连接数据库,以及修改自定义的密码验证(SpringSecurity)

    一 cas 配置数据库 1 在build gradle中引入jar dependencies Other CAS dependencies modules may be listed here compile 34 org apereo c
  • 怎样学好数电

    随着社会的进步和科学技术的发展 xff0c 数字系统和数字设备已广泛应用于各个领域 xff0c 大规模 xff0c 超大规模集成电路技术的不断完善使得数字电路在现代电子系统的比重越来越大 xff0c 数字电路建立了根本是信号的数字处理 xf
  • 嵌入式经典面试题之选择题

    一 单项选择题 1 如下哪一个命令可以帮助你知道shell命令的用法 xff08 A xff09 A man B pwd C help D more 2 Linux分区类型默认的是 xff1a xff08 B xff09 A vfat B
  • 自定义 Windows RE 体验

    发布时间 2009年10月 更新时间 2009年10月 应用到 Windows 7 Windows Server 2008 R2 https technet microsoft com zh cn library dd744576 v 61
  • Java命令行运行错误: 找不到或无法加载主类

    前言 xff1a 虽然学习Java语言约有两年多 xff0c 但在最近需要使用命令行工具编译并运行Java程序时 xff0c 还是报错了 花费了一些时间 xff0c 解决了该问题 xff0c 发现解决方法在初学Java时使用过 一则 xff
  • 开贴记录STM32工程遇到的各种问题及解决方法

    开贴记录STM32工程遇到的各种问题及解决方法 STM32工程问题集锦 针对工程开发过程中常见问题进行备注 文章目录 STM32工程问题集锦问题列表时钟设置串口设置STM32CUBEIDEADCDMA定时器HardFault 处理方法时钟设
  • [1040]DataWorks中MaxCompute的常用操作命令

    文章目录 表操作1 查看表的详细信息 xff1a 2 通过 96 create table as select 96 语句创建表 xff0c 并在建表的同时将数据复制到新表中 xff1a 3 如果希望源表和目标表具有相同的表结构 xff0c
  • [549]python实现K-Means算法

    K Means是一种聚类 Clustering 算法 xff0c 使用它可以为数据分类 K代表你要把数据分为几个组 xff0c 前文实现的K Nearest Neighbor算法也有一个K xff0c 实际上 xff0c 它们有一个相似之处
  • 串口调试工具开发

    刚学习Qt xff0c 搜查资料 xff0c 根据学到的知识 xff0c 完成一个简单的串口调试工具 刚入行 xff0c 谅解 最终效果图 xff0c 图上功能都可实现 UI界面绘制 xff1a 代码如下 xff1a 串口调试工具开发 1