Qt实现串口通讯实例

欢迎小伙伴的点评✨✨,相互学习🚀🚀🚀
博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀

文章目录

  • 前言
  • 一、串口是什么?
  • 二、图示实例
  • 三、实例实例解析
    • mainwindow.h
    • main.cpp
    • mainwindow.cpp
  • 四、总结

前言

本章节将会给大家带来Qt串口通讯软件的简单实例

一、串口是什么?

串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。典型地,串口用于ASCII码字符的传输。通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。
串口: 串口是一个泛称,UART,TTL,RS232,RS485都遵循类似的通信时序协议,因此都被通称为串口。

UART接口: 通用异步收发器(Universal Asynchronous Receiver/Transmitter),UART是串口收发的逻辑电路,这部分可以独立成芯片,也可以作为模块嵌入到其他芯片里,单片机、SOC、PC里都会有UART模块。
COM口: 特指台式计算机或一些电子设备上的D-SUB外形一种连接器结构,VGA接口的连接器也是D-SUB)的串行通信口,应用了串口通信时序和RS232的逻辑电平。
USB口: 通用串行总线,和串口完全是两个概念。虽然也是串行方式通信,但由于USB的通信时序和信号电平都和串口完全不同,因此和串口没有任何关系。USB是高速的通信接口,用于PC连接各种外设,U盘、键鼠、移动硬盘、当然也包括“USB转串口”的模块。(USB转串口模块,就是USB接口的UART模块)

波特率: 这是一个衡量符号传输速率的参数。指的是信号被调制以后在单位时间内的变化,即单位时间内载波参数变化的次数,如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位,1个停止位,8个数据位),这时的波特率为240Bd,比特率为10位*240个/秒=2400bps。一般调制速率大于波特率,比如曼彻斯特编码)。通常电话线的波特率为14400,28800和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,典型的例子就是GPIB设备的通信。
数据位: 这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
停止位: 用于表示单个包的最后一位。典型的值为1,1.5和2位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
奇偶校验位: 在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位为1,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
流控制: 流控可以使数据接收设备在不能接收数据时通知数据发送设备,使其停止发送。串口的流控经常采用硬件流控和软件流控两种方式。

二、图示实例

使用Configure Virtual Serial Port Driver工具模拟串口
GitHub 使用git 命令下载

git clone  https://github.com/dhn111/Qt.git 

Qt串口通信调试工具包
请添加图片描述

三、实例实例解析

先在 ” .pro “ 文件中添加 如下图所示:请添加图片描述

QT       +=serialport

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QComboBox>
#include <QWidget>
#include <QGridLayout>
#include <QMessageBox>
#include <QLabel>
#include <QTextEdit>
#include <QPushButton>
#include <QSerialPort>      //提供访问串口的功能
#include <QSerialPortInfo>  //提供系统中存在的串口的信息
#include <QDebug>
#include <QMessageBox>
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindowQWidget *parent = nullptr);~MainWindow);private:QComboBox *ComboBox_1;   //串口端口QComboBox *ComboBox_2;   //波特率QComboBox *ComboBox_3;   //校验位QComboBox *ComboBox_4;   //数据位QComboBox *ComboBox_5;   //停止位QComboBox *ComboBox_6;   //流控制QLabel    *Label_1;   //串口端口QLabel    *Label_2;   //波特率QLabel    *Label_3;   //校验位QLabel    *Label_4;   //数据位QLabel    *Label_5;   //停止位QLabel    *Label_6;   //流控制QLabel    *Label_7;   //发送数据窗口QLabel    *Label_8;   //接受数据窗口QTextEdit *TextEdit_1; //数据发送窗口QTextEdit *TextEdit_2; //数据接受窗口QPushButton *PushBtton_1; //打开串口按钮QPushButton *PushBtton_2; //数据发送按钮QSerialPort *myport; //串口QGridLayout *layout;     //布局bool OpenPort;         //是否已打开串口void botelvconst QString &arg);  //设置波特率void jiaoyanweiint arg);         //设置校验位void shujuweiconst QString &arg);  //设置数据位void tingzhiweiconst QString &arg);  //设置停止位void liukongzhiint arg1);      //设置流控制public slots :void ON_PushBtton_1);   //打开串口槽函数void ON_PushBtton_2);   //发送数据槽函数void readPort);         //接受串口数据
};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"#include <QApplication>int mainint argc, char *argv[])
{QApplication aargc, argv);MainWindow w;w.show);return a.exec);
}

mainwindow.cpp

#include "mainwindow.h"MainWindow::MainWindowQWidget *parent): QMainWindowparent)
{ComboBox_1 = new QComboBox);   //创建串口组合窗ComboBox_2 = new QComboBox);   //创建波特率组合窗ComboBox_3 = new QComboBox);   //创建校验位组合窗ComboBox_4 = new QComboBox);   //创建数据位组合窗ComboBox_5 = new QComboBox);   //创建停止位组合窗ComboBox_6 = new QComboBox);   //创建流控制组合窗Label_1   = new QLabel"串口端口");Label_2   = new QLabel"波特率");Label_3   = new QLabel"校验位");Label_4   = new QLabel"数据位");Label_5   = new QLabel"停止位");Label_6   = new QLabel"流控制");Label_7   = new QLabel"发送数据窗口");Label_8   = new QLabel"接受数据窗口");TextEdit_1  =  new QTextEdit); //发送数据窗口TextEdit_2  =  new QTextEdit); //接受数据窗口PushBtton_1 = new QPushButton"打开");//打开串口按钮PushBtton_2 = new QPushButton"发送");//数据发送按钮QWidget *centerWindow = new QWidget; //新建widget 类this->setCentralWidgetcenterWindow);  //中间的空间会铺满整个widgetlayout = new QGridLayoutthis);layout->addWidgetComboBox_1,1,2); //创建组合窗 0行,1列layout->addWidgetComboBox_2,2,2);layout->addWidgetComboBox_3,3,2);layout->addWidgetComboBox_4,4,2);layout->addWidgetComboBox_5,5,2);layout->addWidgetComboBox_6,6,2);layout->addWidgetLabel_1,1,1); //创建组合窗 0行,1列layout->addWidgetLabel_2,2,1);layout->addWidgetLabel_3,3,1);layout->addWidgetLabel_4,4,1);layout->addWidgetLabel_5,5,1);layout->addWidgetLabel_6,6,1);layout->addWidgetLabel_7,7,1); //7行,1列layout->addWidgetPushBtton_1,7,2); //7行,2列layout->addWidgetTextEdit_1,8,1,1,2); //8行,1列,长1,宽1layout->addWidgetLabel_8,9,1); //9行,1列,长1,宽1layout->addWidgetPushBtton_2,9,2); //9行,2列layout->addWidgetTextEdit_2,10,1,1,2); //10行,1列,长1,宽1centerWindow->setLayoutlayout); //获取layout并设置控件位置myport = new QSerialPort); //创建串口对象connectmyport, &QSerialPort::readyRead, this, &MainWindow::readPort);//绑定读取串口信息的信号和槽connectPushBtton_1,SIGNALclickedbool)),this,SLOTON_PushBtton_1)));//连接两个信号和槽connectPushBtton_2,SIGNALclickedbool)),this,SLOTON_PushBtton_2)));//连接两个信号和槽//获取允许使用的串口信息QList<QSerialPortInfo> port = QSerialPortInfo::availablePorts);ifport.isEmpty)){ComboBox_1->addItem"无效");}else{foreachconst QSerialPortInfo &port_info, port){ComboBox_1->addItemport_info.portName));}}ComboBox_2->addItem"1200");ComboBox_2->addItem"2400");ComboBox_2->addItem"4800");ComboBox_2->addItem"38400");ComboBox_2->addItem"115200");ComboBox_3->addItem"OddParity");ComboBox_3->addItem"EvenParity");ComboBox_3->addItem"NoParity");ComboBox_4->addItem"5");ComboBox_4->addItem"6");ComboBox_4->addItem"7");ComboBox_4->addItem"8");ComboBox_5->addItem"1");ComboBox_5->addItem"1.5");ComboBox_5->addItem"2");ComboBox_6->addItem"Hardware");ComboBox_6->addItem"Software");ComboBox_6->addItem"NoFlow");OpenPort = false;
}//ui函数未使用
MainWindow::~MainWindow)
{}void MainWindow::ON_PushBtton_1)       //打开串口槽函数实现
{ifOpenPort == false)      //打开串口{//指定串口信息(串口名称)QSerialPortInfo *port = new QSerialPortInfoComboBox_1->currentText));//绑定串口myport->setPort*port);/******* currentText 获取字符串* currentIndex 获取枚举整数********/botelvComboBox_2->currentText)); //设置波特率jiaoyanweiComboBox_3->currentIndex)); //设置校验位shujuweiComboBox_4->currentText)); //设置数据位tingzhiweiComboBox_5->currentText)); //设置停止位liukongzhiComboBox_6->currentIndex)); //设置流控制//打开串口if!myport->openQIODevice::ReadWrite)){QMessageBox::warningthis,"警告","打开串口失败!");return;}PushBtton_1->setTexttr"关闭串口"));OpenPort = true;}else                    //关闭串口{myport->close);PushBtton_1->setTexttr"打开串口"));OpenPort = false;}
}void MainWindow::ON_PushBtton_2)       //数据发送槽函数实现
{QString data = TextEdit_1->toPlainText);  //获取数据QByteArray arg = data.toLatin1);char *temp = arg.data);myport->writetemp); //发送数据
}//接受串口数据
void MainWindow::readPort)
{QByteArray buf;buf = myport->readAll); //接受数据QString data = buf;//qDebug) << data << endl;TextEdit_2->appenddata); //写入到文本框中
}//设置波特率
void MainWindow::botelvconst QString &arg)
{switcharg.toInt)){case 1200:myport->setBaudRateQSerialPort::Baud1200);break;case 2400:myport->setBaudRateQSerialPort::Baud2400);break;case 9600:myport->setBaudRateQSerialPort::Baud9600);break;case 38400:myport->setBaudRateQSerialPort::Baud38400);break;case 115200:myport->setBaudRateQSerialPort::Baud115200);//qDebug)<<"Baud115200";break;}
}//设置校验位
void MainWindow::jiaoyanweiint arg)
{switcharg){case 0:myport->setParityQSerialPort::OddParity);break;case 1:myport->setParityQSerialPort::EvenParity);break;case 2:myport->setParityQSerialPort::NoParity);//qDebug)<<"NoParity";break;}
}//设置数据位
void MainWindow::shujuweiconst QString &arg1)
{switcharg1.toInt)){case 5:myport->setDataBitsQSerialPort::Data5);break;case 6:myport->setDataBitsQSerialPort::Data6);break;case 7:myport->setDataBitsQSerialPort::Data7);break;case 8:myport->setDataBitsQSerialPort::Data8);//qDebug)<<"Data8";break;}
}//设置停止位
void MainWindow::tingzhiweiconst QString &arg)
{switcharg.toInt)){case 1:myport->setStopBitsQSerialPort::OneStop);//qDebug)<<"OneStop";break;case 2:myport->setStopBitsQSerialPort::TwoStop);break;}
}//设置流控制
void MainWindow::liukongzhiint arg)
{switcharg){case 0:myport->setFlowControlQSerialPort::HardwareControl);break;case 1:myport->setFlowControlQSerialPort::SoftwareControl);break;case 2:myport->setFlowControlQSerialPort::NoFlowControl);//qDebug)<<"NoFlowControl";break;}
}

四、总结

QT上位机软件实现串口通讯在嵌入式领域有着广泛的应用。

查看全文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.dgrt.cn/a/2212072.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章:

请添加图片描述

Qt实现串口通讯实例

欢迎小伙伴的点评✨✨,相互学习🚀🚀🚀 博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀 文章目录前言一、串口是什么&amp……

在Vue3中使用NavieUI组件库,美化页面

1 创建Vue3项目 vue create xx 选择Vue3模式
2 安装NavieUI npm i -D naive-ui 3 使用NavieUI 注意,好像只支持按需引用 样例:
<template><div class"hello"><h1>{{ msg }}</h1>
<!– 使用–><NButton&……

【前端】VUE多环境配置

【前端】VUE多环境配置
根目录创建这几个文件
# 开发环境 .env.dev
ENV devVUE_APP_SERVER_API http://localhost:8080/api/pavilion# 集成测试 .env.sit # 验收测试 .env.uat # 生产环境 .env.prod
ENV prodVUE_APP_SERVER_API https://www.wuduoqiang.com/api/pavili……

Spring Security 6.0系列【12】源码篇之会话管理

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo 文章目录 前言1. 核心类1.1 SessionAuthenticationStrategy1.1.1 AbstractSessionFix……

Mybatis高阶使用

1.Mybatis拦截器
Mybatis——拦截器Interceptor_mybatis interceptor_七海健人的博客-CSDN博客
mybatis拦截器使用及原理_metaobject.forobject_huang_ma的博客-CSDN博客
2.Mybatis工具类 MetaObject MetaClass
https://www.cnblogs.com/javaDeveloper/p/13151682.html
3.……

python 获取日期特征(工作日/周末/节假日等)

需求:获取每天对应的日期特征——工作日、周末、节假日、指定节日(如618、双11、双12)业务场景:可以做不同日期类型下的流量、销量对比分析结果预示: 主要运用的python库: chinese_calendar(需要……

VMLogin试用的功能包括哪些?

未使用过VMLogin 的新用户可以联系客服领取免费三天试用; 试用版除了不可使用“添加子账户,不可分享和转移浏览器所有权”的功能,其他功能都与付费版一样。
试用版可使用的功能:
① 同时储存5个浏览器;
② 可创建……

【华为机试真题详解JAVA实现】—坐标移动

目录 一、题目描述
二、解题代码 一、题目描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A或者D或者W或者S) +……

自动处理【微信消费者投诉管理系统】配置指南

大家好,我是小悟
已经有小伙伴开始使用自动处理【微信消费者投诉管理系统】,所以详细介绍一下如何配置。
阅读这篇文章之前,结合这篇【连夜干出来一个自动处理【微信消费者投诉管理系统】,支持多商户】干货食用更佳。 连夜干出来……

webstorm中快速生成自定义注释

演示:…

一、lua基础知识1

一、lua 的数据类型
–类型 a1; –number printtypea)) –number b"HelloWorld"; printtypeb)) –string 两种数据类型 ctrue; printtypec)) –boolean true 或者 false d print; d"HelloWorld"); printtyped)); –function类型 ……

二、lua语言基础2

1.lua的类型有哪些?答:lua的数据类型有:number,string,nil function,table,thread,userdata用户自定义的类型),boolean(布尔类型) 2.什么是尾调用,尾调用有什么优点尾调用:在一个函数的最后一步开始调用另……

quick-cocos2dx-luaUI控件讲解

–MyApp部分 require"config") require"cocos.init") require"framework.init") local MyApp class"MyApp", cc.mvc.AppBase) function MyApp:ctor) MyApp.super.ctorself) end function MyApp:run) cc.FileUti……

quick-cocos2dx lua语言讲解 动作,定时器,触摸事件,工程的类的讲解)

–MainScene部分
— display.newScene 创建一个场景 — 在quick里面我们的控件、精灵 一般是加载到场景上的 local MainScene class"MainScene", function) return display.newScene"MainScene") end) function MainScene:ctor) –创……

使用quick-cocos2dx-lua 实现的小游戏(包含碰撞检测,触屏发子弹)

–主界面local MainScene class"MainScene", function)return display.newScene"MainScene")end)ON true;function MainScene:ctor)local bg cc.Sprite:create"main_background.png");bg:setScale2);bg:setPositiondisplay.cx,display……

cocos2d-js 中scrollview详解

/****
开头的一些废话:
1、多思考,善于思考
2、懂得变通
3、多多查询API首先复制一段 API中的源码:(UIScrollView.js)这段代码可以看出 scrollview
中的容器是一个node,并且他的位置是:代码最后……

cocos2d-js中的回调函数中世界坐标系和节点坐标系的相互转换

世界坐标系和节点坐标系都是OPENGL 坐标系 1、世界坐标系原点就是屏幕的左下角; 2、节点坐标系的原点就是一个节点的左下角; 3、两个坐标系可以通过已经写好的cocosAPI进行想换转换; 4、所有的节点需要转为一个节点上或者是统一的世界坐标系……

通过JavaScript实现漂浮

<html>
<head><meta http-equiv"Content-Type" content"text/html"; charset"gb2312" /><title>漂浮广告</title><style type"text/css">div{position:absolute;}</style>
</head>
&……

序列动画和图片内存问题

一、帧动画问题 /*** 帧动画总结:* 1、如果精灵进行新建时,加载了纹理,那么setRestoreOriginalFrame可以设置为false或者true* 2、如果精灵新建时,没有加载纹理的话,那么setRestoreOriginalFrame需要设置为false&#……

冒泡排序的两种写法

//第一种写法: #include <iostream> using namespace std; void bubbleSortint arr[], int n) { for int i 0; i < n-1; i) { int temp 0; for int j i1; j <n; j) { if arr[i] ……

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注