Qt实现串口通讯实例

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

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


前言

本章节将会给大家带来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串口通信调试工具包
Qt实现串口通讯实例

三、实例实例解析

先在 ” .pro “ 文件中添加 如下图所示:Qt实现串口通讯实例

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_OBJECT

public:
    MainWindow(QWidget *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 botelv(const QString &arg);  //设置波特率

    void jiaoyanwei(int arg);         //设置校验位

    void shujuwei(const QString &arg);  //设置数据位

    void tingzhiwei(const QString &arg);  //设置停止位

    void liukongzhi(int arg1);      //设置流控制

public slots :
    void ON_PushBtton_1();   //打开串口槽函数
    void ON_PushBtton_2();   //发送数据槽函数
    void readPort();         //接受串口数据
};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    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->setCentralWidget(centerWindow);  //中间的空间会铺满整个widget

    layout = new QGridLayout(this);

    layout->addWidget(ComboBox_1,1,2); //创建组合窗 0行,1列
    layout->addWidget(ComboBox_2,2,2);
    layout->addWidget(ComboBox_3,3,2);
    layout->addWidget(ComboBox_4,4,2);
    layout->addWidget(ComboBox_5,5,2);
    layout->addWidget(ComboBox_6,6,2);


    layout->addWidget(Label_1,1,1); //创建组合窗 0行,1列
    layout->addWidget(Label_2,2,1);
    layout->addWidget(Label_3,3,1);
    layout->addWidget(Label_4,4,1);
    layout->addWidget(Label_5,5,1);
    layout->addWidget(Label_6,6,1);
    layout->addWidget(Label_7,7,1); //7行,1列
    layout->addWidget(PushBtton_1,7,2); //7行,2列

    layout->addWidget(TextEdit_1,8,1,1,2); //8行,1列,长1,宽1

    layout->addWidget(Label_8,9,1); //9行,1列,长1,宽1
    layout->addWidget(PushBtton_2,9,2); //9行,2列

    layout->addWidget(TextEdit_2,10,1,1,2); //10行,1列,长1,宽1



    centerWindow->setLayout(layout); //获取layout并设置控件位置

    myport = new QSerialPort(); //创建串口对象

    connect(myport, &QSerialPort::readyRead, this, &MainWindow::readPort);//绑定读取串口信息的信号和槽
    connect(PushBtton_1,SIGNAL(clicked(bool)),this,SLOT(ON_PushBtton_1()));//连接两个信号和槽
    connect(PushBtton_2,SIGNAL(clicked(bool)),this,SLOT(ON_PushBtton_2()));//连接两个信号和槽
    //获取允许使用的串口信息
    QList<QSerialPortInfo> port = QSerialPortInfo::availablePorts();
    if(port.isEmpty())
    {
        ComboBox_1->addItem("无效");
    }
    else
    {
        foreach(const QSerialPortInfo &port_info, port)
        {
            ComboBox_1->addItem(port_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()       //打开串口槽函数实现
{
    if(OpenPort == false)      //打开串口
    {
        //指定串口信息(串口名称)
        QSerialPortInfo *port = new QSerialPortInfo(ComboBox_1->currentText());
        //绑定串口
        myport->setPort(*port);

        /******
         * currentText 获取字符串
         * currentIndex 获取枚举整数
        ********/
        botelv(ComboBox_2->currentText()); //设置波特率
        jiaoyanwei(ComboBox_3->currentIndex()); //设置校验位
        shujuwei(ComboBox_4->currentText()); //设置数据位
        tingzhiwei(ComboBox_5->currentText()); //设置停止位
        liukongzhi(ComboBox_6->currentIndex()); //设置流控制

        //打开串口
        if(!myport->open(QIODevice::ReadWrite))
        {
            QMessageBox::warning(this,"警告","打开串口失败!");
            return;
        }

        PushBtton_1->setText(tr("关闭串口"));
        OpenPort = true;
    }
    else                    //关闭串口
    {
        myport->close();
        PushBtton_1->setText(tr("打开串口"));
        OpenPort = false;
    }
}


void MainWindow::ON_PushBtton_2()       //数据发送槽函数实现
{
    QString data = TextEdit_1->toPlainText();  //获取数据
    QByteArray arg = data.toLatin1();
    char *temp = arg.data();
    myport->write(temp); //发送数据
}

//接受串口数据
void MainWindow::readPort()
{
    QByteArray buf;
    buf = myport->readAll(); //接受数据
    QString data = buf;
    //qDebug() << data << endl;
    TextEdit_2->append(data); //写入到文本框中
}


//设置波特率
void MainWindow::botelv(const QString &arg)
{
    switch(arg.toInt())
    {
    case 1200:
        myport->setBaudRate(QSerialPort::Baud1200);
        break;
    case 2400:
        myport->setBaudRate(QSerialPort::Baud2400);
        break;
    case 9600:
        myport->setBaudRate(QSerialPort::Baud9600);
        break;
    case 38400:
        myport->setBaudRate(QSerialPort::Baud38400);
        break;
    case 115200:
        myport->setBaudRate(QSerialPort::Baud115200);
        //qDebug()<<"Baud115200";
        break;
    }
}

//设置校验位
void MainWindow::jiaoyanwei(int arg)
{
    switch(arg)
    {
    case 0:
        myport->setParity(QSerialPort::OddParity);
        break;
    case 1:
        myport->setParity(QSerialPort::EvenParity);
        break;
    case 2:
        myport->setParity(QSerialPort::NoParity);
        //qDebug()<<"NoParity";
        break;
    }
}

//设置数据位
void MainWindow::shujuwei(const QString &arg1)
{
    switch(arg1.toInt())
    {
    case 5:
        myport->setDataBits(QSerialPort::Data5);
        break;
    case 6:
        myport->setDataBits(QSerialPort::Data6);
        break;
    case 7:
        myport->setDataBits(QSerialPort::Data7);
        break;
    case 8:
        myport->setDataBits(QSerialPort::Data8);
        //qDebug()<<"Data8";
        break;
    }
}

//设置停止位
void MainWindow::tingzhiwei(const QString &arg)
{
    switch(arg.toInt())
    {
    case 1:
        myport->setStopBits(QSerialPort::OneStop);
        //qDebug()<<"OneStop";
        break;
    case 2:
        myport->setStopBits(QSerialPort::TwoStop);
        break;
    }
}

//设置流控制
void MainWindow::liukongzhi(int arg)
{
    switch(arg)
    {
    case 0:
        myport->setFlowControl(QSerialPort::HardwareControl);
        break;
    case 1:
        myport->setFlowControl(QSerialPort::SoftwareControl);
        break;
    case 2:
        myport->setFlowControl(QSerialPort::NoFlowControl);
        //qDebug()<<"NoFlowControl";
        break;
    }
}

四、总结

QT上位机软件实现串口通讯在嵌入式领域有着广泛的应用。文章来源地址https://www.toymoban.com/news/detail-409192.html

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

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

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

相关文章

  • 【STM32通讯系列--串口通讯】使用标准库、HAL库实现任意长度数据的收发(包含帧头、帧尾校验,配套完整开源程序)

    【数据组成】串口的通讯协议由开始位,数据位,校验位,结束位构成。 【数据结构】一般以一个低电平作为一帧数据的起始,接着跟随 8 位或者 9 位数据位,之后为校验位,分为奇校验,偶校验和无校验,最后以一个先高后低的脉冲表示结束位,长度可以设置为 0.5,1,

    2024年02月14日
    浏览(33)
  • qt websocket 通讯实现消息发送接收

    websocket 是基于 TCP socket 之上的应用层, 解决 HTML 轮询连接的问题,实现客户端与服务端长连接, 实现消息互相发送,全双工。 服务端, 使用 QT 教程demo chatserver.h chatserver.cpp main.cpp 客户端 clientwidget.h clientwidget.cpp websocketclient.h websocketclient.cpp

    2024年02月15日
    浏览(34)
  • 基于MATLAB App搭建STM32用户交互界面(1)——MATLAB与STM32串口通讯的实现

            最近几个月,DIY了块板子,选用的芯片是STM32F407,该板子与上位机(也就是电脑)的通讯方式有两种,一是用串口发送程序进程数据,二是用网口发送原始数据。在调试时,需要用XCOM接收串口信息、用XNET接收网口信息。由于这块板子是用来学术研究的,数据每次

    2024年02月09日
    浏览(36)
  • 基于STM32F1以及STM32CubeMx实现串口中断通讯(字符串发送与接收)

    首先选好自己的板子并打开软件设置,本实验基于STM32F103ZET6实现,打开软件后如图: 打开外部高速晶振,然后接着配置时钟: 将时钟频率修改为72MHz,接着设置接线方式为SW 接下来需要使用串口中断通讯,打开我们的串口设置并打开中断 这里波特率设置为115200,数据位为

    2024年02月09日
    浏览(36)
  • Qt实现UDP高速通讯,下位机为FPGA

    目录 一、为什么要写这篇文章,因为我就是要另辟蹊径,当然也是汲取了网上大咖们的经验,尽量简洁的进行总结 二、关于接收数据需的条件,需要绑定本地IP地址和端口号,可解释为此时为服务器模式,远端为客户端模式,实现的代码非常简单几行代码可以搞定 三、数据

    2024年02月12日
    浏览(23)
  • [Qt网络编程]之UDP通讯的简单编程实现

    hello!欢迎大家来到我的Qt学习系列之 网络编程之UDP通讯的简单编程实现。 希望这篇文章能对你有所帮助!!! 本篇文章的相关知识请看我的上篇文章: 目录 UDP通讯  基于主窗口的实现  基于线程的实现          UDP数据报协议是一个面向无连接的传输层报文协议 ,它简

    2024年04月25日
    浏览(41)
  • STM32G0+EMW3080+阿里云实现单片机WiFi智能联网功能(一)EMW3080实现和PC之间的串口通讯

    项目描述:该系列记录了STM32G0+EMW3080实现单片机智能联网功能项目的从零开始一步步的实现过程; 硬件环境:单片机为STM32G030C8T6;物联网模块为EMW3080V2-P;网联网模块的开发板为MXKit开发套件,具体型号为XCHIP MXKit-Base V2.2; 软件环境:STM32需要的软件有STM32CubeMX和STM32CubeIDE;

    2024年02月10日
    浏览(43)
  • 学习如何在C#中轻松实现串口数据接收:清晰步骤与实例代码

      概述: 以上C#示例演示了如何使用SerialPort类实现串口数据接收。通过设置串口属性、定义数据接收事件处理程序,你可以轻松地打开串口、监听数据,并在事件处理程序中对接收到的数据进行处理。这提供了一个基本框架,可根据实际需求进行定制。 在C#中实现串口数据接

    2024年02月22日
    浏览(37)
  • 用C++QT实现一个modbus rtu通讯程序框架

    下面是一个简单的Modbus RTU通讯程序框架的示例,使用C++和QT来实现: 具体的数据处理将根据需求进行扩展和实现,如写入数据和处理异常等。另外,需要根据实际情况设置正确的串口参数和设备地址,并确保与Modbus设备的正确连接。在编译和运行程序之前,还需要在项目的

    2024年02月06日
    浏览(48)
  • 基于Qt的多线程TCP即时通讯软件的设计与实现

    本文将从涉及到主要技术开始,讲解使用Qt来实现一个支持多客户端链接的 多线程TCP服务器 及其 客户端 的设计与实现的解决方案。 注:本文使用的开发环境为Qt5.15.2, 使用MSVC2019_64编译器, C++11及以上 接下来我将会详细讲解客户端和服务端的设计与实现的关键细节。完整的源

    2024年01月16日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包