QT 篇 QT上位机串口编程

这篇具有很好参考价值的文章主要介绍了QT 篇 QT上位机串口编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QT应用篇

一、QT上位机串口编程
二、QML用Image组件实现Progress Bar 的效果
三、QML自定义显示SpinBox的加减按键图片及显示值效果



QT 篇 一、QT上位机串口编程

最近因为项目需要,需要用到上位机,通过串口与上位机进行通讯,来上传和下发一些数据以及控制指令,所以用QT写了一个上位机,并记录下来,免得到时候要用又到处翻资料。

QT版本:QT Creater 4.80
硬件:stm32 + 串口转ttl模块

2023-12-28 更新
可以通过安装虚拟串口来模拟串口通信的情况

软件: Virtual Serial Port Driver 7.2
可以生成虚拟串口 无需实际硬件串口就可以实现同一台电脑上串口模拟通信 方便调试串口助手

链接:https://pan.baidu.com/s/1GuQ8UoojWZk-YjsnDhqurg?pwd=2023
提取码:2023

–来自百度网盘超级会员V5的分享

安装好了之后打开

QT 篇 QT上位机串口编程

点击Add pair
QT 篇 QT上位机串口编程
生成一对虚拟串口 COM1 和COM2
QT 篇 QT上位机串口编程
虚拟串口测试

QT 篇 QT上位机串口编程
后续可以使用虚拟串口来调试,这样就不需要ch430来才能调试了

默认安装好QT了

1.新建工程

选择Qt Widgets

然后下一步
QT 篇 QT上位机串口编程
自己填一个项目名字和项目路径
QT 篇 QT上位机串口编程
我只安装了这一个,我就选了这个
QT 篇 QT上位机串口编程

这里主要是一些基类的选择
这里我选择QMainWindow

类名,文件名什么的,你们看看要不要改名

QT 篇 QT上位机串口编程
项目管理这里版本控制选择无
QT 篇 QT上位机串口编程
然后就完成了创建了

2.添加类和库文件

QT5自带有串口的封装库 QSerialPort ,我们要用的相关的函数,所以要在.pro文件里面添加一样代码,在QT += core gui的基础上添加serialport

QT       += core gui serialport

在mainwindo.h里添加串口的一些库

#include <QSerialPort>			//访问串口的库
#include <QSerialPortInfo>		//查询串口信息的库
#include <QDebug>				//用于调试打印输出的库
#include <QTimer>				//定时器的库
#include <QTime>				//时间的库
#include <QDate>				//日期的库
#include <QMessageBox>			//一个小的弹窗库

其实上面这些这需要添加最顶上的了两个就够了,其余的是我有其他的用处就加了进去

3.设计上位机页面

这是我自己设计好的上位机

QT 篇 QT上位机串口编程
布局上参考了一下正点原子的XCOM串口软件

QT 篇 QT上位机串口编程

上位机页面
先设置好窗口的大小固定位800x480
窗口最大和最小都是800x480 这样一来就没办法拉伸了,就不会影响美观

QT 篇 QT上位机串口编程
然后可以按照我的设计页面来摆放一些控件

当然你们也可以不用这么多控件,因为实际上来说,需要修改的串口参数其实就只有名称和波特率而已,其余的是可以固定不做改变的

看需求

对象的名称最好改一下,不然到时候编写代码的时候你会不记得哪个代表哪一个部件,我的部件的名称

QT 篇 QT上位机串口编程
对象名称
QT 篇 QT上位机串口编程
摆放好这些部件后
分别添加波特率
停止位
数据位
奇偶校验等等

QT 篇 QT上位机串口编程
然后设置Combox的初始值

我把串口的波特率设置为115200是初始值
其余的你们看着来
CurrentIndex的索引和数组一样,从0开始
QT 篇 QT上位机串口编程

4.添加函数 扫描串口和初始化串口设置

在mainwindow.h里的
private:

    //定时器
    QTimer *timer;
    // 串口对象
    QSerialPort *serialport;
    //扫描串口
    void scanSerialPort();
    //初始化
    void serialPortInit();

public

    int btn_on_off = 0;

    int btn_state = 0;

mainwindow.cpp文件


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
	//对象实例化
    serialport = new QSerialPort(this);
	
    timer = new QTimer(this);
	
    scanSerialPort();

}

void MainWindow::scanSerialPort()
{
	//查询可用的串口信息
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        {
        	//添加串口到下拉菜单
             ui->cbx_setPortName->addItem(info.portName());
        }
        qDebug()<<"已发现串口:"<<ui->cbx_setPortName->currentText();
    }
}



void MainWindow::serialPortInit()
{
    //设置串口名称
    serialport->setPortName(ui->cbx_setPortName->currentText());
   qDebug()<<"串口名称:"<<serialport->portName();

   if (!serialport->open(QIODevice::ReadWrite))
   {
		qDebug()<<"错误,串口无法打开,可能被占用!";
		QMessageBox::about(this,"错误","串口无法打开,可能被占用!");
		serialport->close();
		return ;
   }

    //波特率
    serialport->setBaudRate(ui->cbx_setBaudRate->currentText().toInt());
    qDebug()<<"波特率:"<<ui->cbx_setBaudRate->currentText().toInt();
    //停止位
    switch (ui->cbx_setStopBits->currentText().toInt())
    {
    case 1 :  serialport->setStopBits(QSerialPort::OneStop); break;
    case 2 :  serialport->setStopBits(QSerialPort::TwoStop); break;
        default: break;
    }
    qDebug()<<"停止位:"<<serialport->stopBits();
    //数据位
    switch (ui->cbx_setDataBits->currentText().toInt())
    {
    case 5 :  serialport->setDataBits(QSerialPort::Data5); break;
    case 6 :  serialport->setDataBits(QSerialPort::Data6); break;
    case 7 :  serialport->setDataBits(QSerialPort::Data7); break;
    case 8 :  serialport->setDataBits(QSerialPort::Data8); break;
        default: break;
    }
    //奇偶位
     switch (ui->cbx_setParity->currentIndex())
    {
    case 0 :  serialport->setParity(QSerialPort::NoParity); break;
    case 1 :  serialport->setParity(QSerialPort::OddParity); break;
    case 2 :  serialport->setParity(QSerialPort::EvenParity); break;
        default: break;
    }
    qDebug()<<"奇偶位:"<<serialport->parity();

    serialport->setFlowControl(QSerialPort::NoFlowControl) ;


}

然后打开ui文件

找到打开串口这个PushButton

转到槽函数

就会自动帮你生成信号函数和槽函数

QT 篇 QT上位机串口编程
打开串口的槽函数

void MainWindow::on_btn_open_close_clicked()
{
         if (btn_on_off == 0)
         {

             ui->cbx_setPortName->setEnabled(false);
             ui->cbx_setBaudRate->setEnabled(false);
             ui->cbx_setDataBits->setEnabled(false);
             ui->cbx_setStopBits->setEnabled(false);
             ui->cbx_setParity->setEnabled(false);
             ui->btn_open_close->setText("关闭串口");
             qDebug()<<"打开串口:";
             serialPortInit();
         }

        if (btn_on_off == 1)
        {

            serialport->close();
            ui->cbx_setPortName->setEnabled(true);
            ui->cbx_setBaudRate->setEnabled(true);
            ui->cbx_setDataBits->setEnabled(true);
            ui->cbx_setStopBits->setEnabled(true);
            ui->cbx_setParity->setEnabled(true);
            ui->btn_open_close->setText("打开串口");
        }
        btn_on_off = !btn_on_off;
}

到这里基本上就可以成功打开串口了
QT 篇 QT上位机串口编程

5. 读串口函数 serialport->readAll();

在mainwindow.h 的private slots: 添加

    void serialPortReadyRead();

    void serialPortWrite();

对应的槽函数

void MainWindow::serialPortReadyRead()
{
    QByteArray temp = serialport->readAll();  
     QString str = ui->textEdit_rx->toPlainText();
     str =  QString::fromLocal8Bit(temp);//显示中文
      ui->textEdit_rx->append(str);
}
    

此时要手动链接信号函数和槽函数
mainwindow.cpp的MainWindow::MainWindow(QWidget *parent) :添加

    connect(serialport,SIGNAL(readyRead()),this,
                              SLOT(serialPortReadyRead()));
                              
     //SIGNAL 是信号函数,QT的串口自带了
     //SLOT是自己定义的槽函数
                          

按着ctrl点击readyRead(),就可以跳转到这里:

QT 篇 QT上位机串口编程

6.写串口函数 serialport->write(buff);

void MainWindow::serialPortWrite()
{
    QByteArray buff;
	//判断是否非空
    if(!ui->textEdit_tx->toPlainText().isEmpty())
    {
        buff = ui->textEdit_tx->toPlainText().toLocal8Bit();//可以写中文
        serialport->write(buff);
    }
}

把serialPortWrite()关联到发送的槽函数下
顺便把清空接收和清空发送也关联起来

void MainWindow::on_btn_clear_rx_clicked()
{
    ui->textEdit_rx->clear();
}

void MainWindow::on_btn_clear_tx_clicked()
{
    ui->textEdit_tx->clear();
}

void MainWindow::on_btn_sent_clicked()
{
    serialPortWrite();
}

接下来就是测试结果

第一个是stm32打印的上来的串口信息

第二个是自发自收(usb转串口的tx和rx短接)

QT 篇 QT上位机串口编程

分割线:=======================================================================================
2022-11-04新增修订

评论区有小伙伴提出没有自刷新串口的功能,以及str += QString::fromLocal8Bit(temp);

现在去掉“+”号,变成str = QString::fromLocal8Bit(temp);

在原有的基础上

增加一个函数

mainwindows.cpp

void MainWindow::reflash_com()
{

    ui->cbx_setPortName->clear();//清除选择串口下拉栏添加的所有项目
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        {
            ui->cbx_setPortName->addItem(info.portName());
        }
    }
    ui->cbx_setPortName->setCurrentIndex(choose_index);
    qDebug()<<"choose_index:"<<choose_index;
}

此外增加一个变量choose_index 用于记录上次选择串口的项目index

函数和变量记得在对应的.h文件增加声明

同时把reflash_com()放到500ms定时器里面

void MainWindow::timer_500ms()
{
    QTime time = QTime::currentTime();
    QDate date = QDate::currentDate();
    ui->label_Date_Time->setText(date.toString("yyyy-MM-dd") +" "+ time.toString("hh:mm:ss"));
    ui->textEdit_rx->setFontPointSize(ui->cbx_setFontPointSize->currentText().toInt());
    
    if (btn_on_off == 0)//判断串口处于未打开状态
    {
      choose_index = ui->cbx_setPortName->currentIndex();
      reflash_com();
    }
}

效果:
QT 篇 QT上位机串口编程文章来源地址https://www.toymoban.com/news/detail-400981.html

到了这里,关于QT 篇 QT上位机串口编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT串口调试助手开发教程:上位机接收数据解析数据帧+多通道波形显示+数据保存

    在该设计中主要需要解决的问题就是接收单片机采集到的数据并在上位机将数字实时的通过波形显示出来,然后上位机要有保存下数据文件的功能,便于后续的软件读取数据做进一步的分析处理。有些人吃相难看,无底线,无道德,鉴于串口上位机会被广泛使用,撰写该教程

    2024年02月07日
    浏览(44)
  • qt串口编程

    第一步在pro文件加入: 第二步需要加入的头文件: 第三步获取当前电脑可用串口名字: 第四步定义一个串口对象并且设置串口名字,数据,校验,停止等等:

    2024年02月12日
    浏览(29)
  • Linux串口应用编程

    在Linux系统中,操作设备的统一接口就是: open/ioctl/read/write 。 对于UART,又在 ioctl 之上封装了很多函数,主要是用来设置行规程。 所以对于UART,编程的套路就是: 使用 open 函数打开串口 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回 read/w

    2024年02月04日
    浏览(24)
  • 51单片机编程应用(C语言):串口通信

    目录 通信的基本概念和种类    1.1串行通信与并行通信 ​编辑 1.2同步通信与异步通信 1.3单工,半双工,全双工   1.4通信速率  二、波特率和比特率的关系 串口通信简介: 1.接口标准 RS-232 2、D型9针接口定义 3.通信协议: 2.串口内部结构  51单片机串口相关寄存器   1.80c

    2024年02月19日
    浏览(49)
  • C++MFC 串口通信 上位机

    本节介绍         在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。串口通信方便易行,应用广泛。         一般情况下,工控机和各智能仪表通过RS485总线进行通信。RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮

    2024年02月12日
    浏览(42)
  • C#上位机的USB通信与串口通信接口区别

    USB通信与串口通信接口的代码区别有以下几个方面: 通信方式不同:串口通信采用全双工或半双工通信方式,而USB通信采用异步、同步和批量传输等多种传输方式。 端口号设置不同:串口通信设置端口号,如\\\"COM1\\\"、\\\"COM2\\\"等,而USB通信通过设备描述符和VID/PID等参数进行识别和

    2024年02月08日
    浏览(44)
  • STM32与Python上位机通过USB虚拟串口通信

    在详细阅读广大网友的教程之后,我对STM32和Python通过USB通信的流程烂熟于心。 尝试用ST公司的NUCLEO-L476RG板子进行简单的回环通信测试,发现还是存在网上无法找到的问题,这个耽搁了几天,期间找到了原因,但没有焊接调试,所以暂时就不以它为例子进行写了。 后采用正点

    2024年02月15日
    浏览(38)
  • 使用Microsoft Visual Studio编写C#上位机(串口助手)

    最近跟着刘工写了一套用于单片机与电脑通信的串口助手,此处将自己手敲的代码记录下来,供大家一起学习交流。 一、程序界面   程序界面 程序界面说明    二、代码(Form1.cs)  三、备注 此处在Form1的属性中,将AutoSize设为True,AutoScroll设为True,AutoScaleMode设为Font,以应

    2024年02月11日
    浏览(51)
  • 【PyQt】PyQt5进阶——串口上位机及实时数据显示

    【Python】PyQt5入门   最近在用PyQt做一个串口上位机,需要串口通信和实时显示曲线。这里简单记录一些关键点。   这个是在安装PyQt5时自动安装的组件,使用方法比较简单,主要是两个模块: QSerialPort , QSerialPortInfo   以上就是串口部分的代码,比较简单,利用代码提

    2024年02月12日
    浏览(54)
  • Matlab上位机——串口收发、接收转为图像实时显示、图像放大缩小等功能

    原例程代码可以进行串口接收发送,加载与存储数据 本人在例程代码的基础上添加了共三个功能 1.加载文件数据,三通道同时显示波形 2.放大缩小 3.均值滤波 4.将接收到的数据以固定位数转换为实时波形 布局 加载文件数据后(excel的csv格式) 滤波效果 实时波形采集当时忘了

    2024年02月02日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包