通过QT基于C++实现串口通信

1.软件下载

本文所用到的所有软件都在以下连接可以下载

QT下载(注意下载路径最好全英,不要出现中文容易有bug)

链接:https://pan.baidu.com/s/1XCPlTBQ8fBOKBYO-H0mSVg?pwd=m28f 
提取码:m28f

串口工具下载

链接:https://pan.baidu.com/s/19Wc4XuANIZeaB6Qz1jeb6w?pwd=ysez 
提取码:ysez

1.添加串口

添加的串口最好选大一点的,编号小的串口一般系统在用。

选择要添加的串口号,点击添加端口

测试端口之间是否可以正常通信

确保串口设置的参数相同

打开串口

在串口数据接受模块输入数据并发送,检测是否正常通信

2.建立QT文件

输入文件名和地址,点击下一步

下一步

基类选择QWidget,点击下一步

3.代码

uart.pro

#-------------------------------------------------
#
# Project created by QtCreator 2024-07-01T11:52:24
#
#-------------------------------------------------

QT       += core gui serialport    #串口通信
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = uart
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSerialPort>  //串口编程

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    void InitWidget();

private slots:
    void on_open_bt_clicked();   //打开串口函数
    void OnReadyData();

    void on_send_bt_clicked();

private:
    Ui::Widget *ui;
    QSerialPort *m_pSerial;  //数据类型为指向串口的指针
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.InitWidget();
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>  //Qt 提供的输出调试信息的工具。

Widget::Widget(QWidget *parent) : //Widget类继承自QWidget
    QWidget(parent),
    ui(new Ui::Widget)//通过ui对象初始化界面布局
{
    ui->setupUi(this);
    m_pSerial = NULL;//初始化m_pSerial为NULL,用于管理串口对象。
}

Widget::~Widget() //析构函数释放了ui对象。
{
    delete ui;
}

void Widget::InitWidget()  //设置界面初始状态,创建串口对象
{
    qDebug()  << "Widget::InitWidget() enter";   //输出
    if (NULL  == m_pSerial)
    {
        m_pSerial  = new QSerialPort(this);
        connect(m_pSerial, SIGNAL(readyRead()), this, SLOT(OnReadyData()));
        //这是一个 Qt 中的信号与槽语法,其中m_pSerial是一个串口对象,readyRead()是serialPort对象的一个信号,表示有数据可以读取。
        //this 是一个指向当前类的指针,onReadyRead()是当前类中的一个槽函数,用于处理seria1Port对象的readyRead()信号。
    }

    ui->data_edit->setEnabled(false); //按钮不可点击
    ui->textEdit->setEnabled(false);
    ui->send_bt->setEnabled(false);

    qDebug()  << "Widget::InitWidget() exit";
}

void Widget::on_open_bt_clicked()  //打开或关闭串口,并设置串口的参数(波特率、数据位、停止位、校验位等)
{
    qDebug()  << "Widget::on_open_bt_clicked() enter";
    if (NULL == m_pSerial)
    {
        qDebug()  << "serial obj error";
        return;
    }
    QString strBt = ui->open_bt->text();  //获取open_bt的按钮的文本内容,并将其存储在变量 strBt 中
    if (strBt == "open")  //检查一个按钮的文本内容,并根据按钮文本的不同执行不同的操作
    {
        QString strCom = ui->uart_com->currentText();  //ui->uart_com是一个下拉框,currentText()用于获取当前选中的文本内容,即串口名称。
        if (strCom.length() == 0) //串口名称的长度为0,错误
        {
            qDebug() << "com port error";
            return;
        }
        m_pSerial->setPortName(strCom); //串口名
        m_pSerial->setBaudRate(QSerialPort::Baud9600);  //波特兰
        m_pSerial->setDataBits(QSerialPort::Data8);  //数据位
        m_pSerial->setStopBits(QSerialPort::OneStop);  //停止位
        m_pSerial->setParity(QSerialPort::NoParity);  //校验位
        m_pSerial->setFlowControl(QSerialPort::NoFlowControl);  //流控制

        if (!m_pSerial->isOpen())  //判断串口m_pSerial 是否已经打开,若未打开
        {
            if (m_pSerial->open(QIODevice::ReadWrite))  //QSerialPort类的方法,用于尝试以读写模式打开串口。若成功打开执行以下内容
            {
                qDebug()  <<  "open ok";
                ui->open_bt->setText("close");  //按钮上的文字变为close
                ui->data_edit->setEnabled(true);  //按钮可点击
                ui->textEdit->setEnabled(true);
                ui->send_bt->setEnabled(true);
                ui->uart_com->setEnabled(false);
            }
            else
            {
                qDebug()  << "open error";
            }
        }
    }
    else
    {
        m_pSerial->close();
        ui->open_bt->setText("open");  //按钮上的文字变为open
        ui->data_edit->setEnabled(false);
        ui->textEdit->setEnabled(false);
        ui->send_bt->setEnabled(false);
        ui->uart_com->setEnabled(true);
    }
    qDebug()  << "Widget::on_open_bt_clicked() exit";
}

void Widget::OnReadyData() //串口数据就绪槽函数,当串口有数据可读时,该函数会被调用
{
    qDebug()  << "Widget::OnReadyData() enter";
    QByteArray arr = m_pSerial->readAll();  //读取串口的所有数据,并将其转换为字符串
    QString strData = ui->textEdit->toPlainText();  //从名为textEdit的文本编辑框中获取纯文本内容,存储在strData中。
    //toPlainText(): 是QTextEdit类的方法,用于获取文本编辑框中的所有纯文本内容。
    if (strData.length() > 0)
    {
        strData.append("\nrecv: ");  //将一个字符串 "\nrecv: " 追加到已经存在的strData变量中。
    }
    else
    {
        strData.append("recv: ");
    }
    strData.append(QString(arr));  //将一个QByteArray类型的变量arr转换为QString类型,并将其追加到strData变量的末尾。
    ui->textEdit->setText(strData);  //将接收到的数据附加到界面上的文本编辑框 textEdit 中,并显示为接收的数据
    qDebug()  << "Widget::OnReadyData() exit";
}

void Widget::on_send_bt_clicked() //发送数据按钮的槽函数
{
    qDebug()  << "Widget::on_send_bt_clicked() enter";
    QString strData = ui->data_edit->text(); //当点击发送数据按钮时,首先获取用户输入的数据
    if (strData.length() == 0)  //如果发送的数据长度为0,输出发送数据长度为0
    {
        qDebug() << "send data length is 0";
        return;
    }
    int iRet = m_pSerial->write(strData.toStdString().data());  //将数据发送到串口,并返回发送字节数
    if (iRet != -1)
    {
        QString strText = ui->textEdit->toPlainText();  //从名为textEdit的文本编辑框中获取当前显示的所有纯文本内容,并将其存储在strText中。
        if (strText.length() > 0)
        {
            strText.append("\nsend: ");
        }
        else
        {
            strText.append("send: ");
        }
        strText.append(strData);
        ui->textEdit->setText(strText);  //如果发送成功,将发送的数据附加到界面上的文本编辑框 textEdit 中,并显示为发送的数据
    }
    qDebug()  << "Widget::on_send_bt_clicked() exit";
}

widget.ui

这里直接用模块进行搭建,不需要用代码。不想搭建的也可以直接用下面的代码。

注意右上角的对象和类。对象名和类必须和这里一样,不然上面代码有的地方要改。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>611</width>
    <height>418</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QComboBox" name="uart_com">
   <property name="geometry">
    <rect>
     <x>100</x>
     <y>30</y>
     <width>87</width>
     <height>22</height>
    </rect>
   </property>
   <item>
    <property name="text">
     <string>COM1</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM2</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM3</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM4</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM5</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM6</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM7</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM8</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM9</string>
    </property>
   </item>
   <item>
    <property name="text">
     <string>COM10</string>
    </property>
   </item>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>30</y>
     <width>72</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>串口号</string>
   </property>
  </widget>
  <widget class="QPushButton" name="open_bt">
   <property name="geometry">
    <rect>
     <x>280</x>
     <y>30</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>open</string>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>80</y>
     <width>371</width>
     <height>221</height>
    </rect>
   </property>
  </widget>
  <widget class="QLineEdit" name="data_edit">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>330</y>
     <width>271</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="send_bt">
   <property name="geometry">
    <rect>
     <x>320</x>
     <y>330</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>send</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

4.测试

点击运行

输入刚刚创建的串口号,点击open

输入要发送的内容

点击send发送

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值