QT开发串口助手(四)——实现发送数据功能

本文介绍了使用Qt进行串口通信的实现,包括如何完善接收中文功能,通过QSerialPort库设置串口参数,并实现打开/关闭串口的功能。此外,还展示了如何添加发送数据功能,通过点击按钮发送固定字符串到串口,并能接收到下位机的回应。
摘要由CSDN通过智能技术生成

今天我们首先来完善数据接收功能, 同时完成数据发送功能

一. 完善数据接收功能

主要有以下几点需要完善:

  • 需要接收中文
  • 打开串口的pushbotton,点击打开后需要改为关闭串口功能

1. 完善接收中文功能

这一块我在帮助手册上是找不到解决办法,只能在网上看有没有解决办法了, 参考了网上这位博主的https://blog.csdn.net/ouening/article/details/89469468,接收函数修改为

/*显示串口数据函数*/
void MainWindow::displayData()
{
    QByteArray rx_data;
    rx_data = this->serialPortUsing.readAll();

    QString str = QString::fromLocal8Bit(rx_data);

    qDebug() << str;
    rx_data.clear();
}

就可以愉快的显示中文了
在这里插入图片描述

2. 完善打开串口和关闭串口功能

做这个功能的思路是先定义一个bool类型的打开与否标志位,点击了打开串口就把这个标志位翻转,再次点击时 在槽函数里面判断这个标志位,做相应的打开或者关闭操作。
mainwindow.cpp代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QComboBox>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*显示波特率*/
    this->BaudList << "9600" << "19200" <<"115200";
    ui->baudComboBox->addItems(this->BaudList);
    /*刷新串口*/
    this->refreshPort();
    /* 点击刷新功能显示*/
    connect(ui->refreshPortBtn, &QPushButton::clicked, this, &MainWindow::refreshPort);
    /* 点击打开串口*/
    connect(ui->openSerialBtn, &QPushButton::clicked, this, &MainWindow::openPort);
    /* 显示串口数据 */
    connect(&this->serialPortUsing, &QSerialPort::readyRead , this, &MainWindow::displayData);
}

/*刷新串口处理函数*/
void MainWindow::refreshPort()
{
    qDebug() << "刷新串口";
    /*清除comboxBox的内容,防止显示重复的串口*/
    ui->displayPortComboBox->clear();

    /* 读取可以使用的串口*/
    this->avaiPortsList = QSerialPortInfo::availablePorts();
    /* 提取串口个数*/
    int avaiPortNum = avaiPortsList.length();

    /*逐个显示*/
    for(int i = 0; i < avaiPortNum; i++)
    {
        ui->displayPortComboBox->addItem(this->avaiPortsList[i].portName());
    }
}

/*打开串口处理函数*/
void MainWindow::openPort()
{
    if(!this->isOpenSerial)
    {
        /*读取当前的波特率和端口号*/
        qDebug() << "打开串口号:"<< ui->displayPortComboBox->currentText()<<"波特率:"<<ui->baudComboBox->currentText().toInt();

        /* 获取串口序号和波特率序号 */

        /*设置当前串口号*/
        int displayPortComboBoxCurrIndex = ui->displayPortComboBox->currentIndex();
        this->serialPortInfoUsing = this->avaiPortsList[displayPortComboBoxCurrIndex];
        this->serialPortUsing.setPort(this->serialPortInfoUsing);
        /*设置波特率*/
        this->serialPortUsing.setBaudRate(ui->baudComboBox->currentText().toInt());
        /*设置数据位:8位*/
        this->serialPortUsing.setDataBits(QSerialPort::Data8);
        /*设置停止位: 1位*/
        this->serialPortUsing.setStopBits(QSerialPort::OneStop);
        /*设置校验位: 无校验*/
        this->serialPortUsing.setParity(QSerialPort::NoParity);
        /*设置流控制: 无硬件流控制*/
        this->serialPortUsing.setFlowControl(QSerialPort::NoFlowControl);
        /*打开串口*/
        if(this->serialPortUsing.open(QIODevice::ReadWrite))
        {
            qDebug() << "打开串口成功!";
            this->isOpenSerial = true;
            ui->openSerialBtn->setText("关闭串口");
        }
        else
        {
            qDebug() << "打开串口失败!";
        }
    }
    else
    {
        qDebug() << "关闭串口";
        this->isOpenSerial = false;
        this->serialPortUsing.close();
        ui->openSerialBtn->setText("打开串口");
    }
}

/*显示串口数据函数*/
void MainWindow::displayData()
{
    QByteArray rx_data;
    rx_data = this->serialPortUsing.readAll();

    QString str = QString::fromLocal8Bit(rx_data);

    qDebug() << str;
    rx_data.clear();
}
MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    /* 定义可用端口列表变量*/
    QList<QSerialPortInfo> avaiPortsList;
    /* 定义波特率列表*/
    QStringList BaudList;
    /* 定义正在使用的串口对象*/
    QSerialPort serialPortUsing;
    /* 定义正在使用的串口信息对象*/
    QSerialPortInfo serialPortInfoUsing;
    /* 定义是否打开串口标志位 */
    bool isOpenSerial = false;
    /*刷新串口信号*/
    void refreshPort(void);
    /*打开串口信号*/
    void openPort(void);
    /*显示串口数据*/
    void displayData(void);
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

实验现象

二. 完善数据发送功能

整体思路:首先页面上增加一个按键, 点击按键时发送一个固定的字符串到下位机。

1. 页面布局

在这里插入图片描述

2. 代码实现

发送数据的方法是write函数

  • 首先是绑定信号和槽函数
/* 发送串口数据 */
    connect(ui->sendDataBtn, &QPushButton::clicked, this, &MainWindow::sendData);
  • 然后再写发送测试函数
/*发送串口数据函数*/
void MainWindow::sendData()
{
    this->serialPortUsing.write("hello world!\r\n");
}
  • 写下位机程序
    我这里直接把下位机的TX和RX短接了,相当于上位机发送什么,下位机就会返回什么,这样就可以看见返回的数据了。
  • 实验效果
    在这里插入图片描述
    mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QComboBox>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    /*显示波特率*/
    this->BaudList << "9600" << "19200" <<"115200";
    ui->baudComboBox->addItems(this->BaudList);
    /*刷新串口*/
    this->refreshPort();
    /* 点击刷新功能显示*/
    connect(ui->refreshPortBtn, &QPushButton::clicked, this, &MainWindow::refreshPort);
    /* 点击打开串口*/
    connect(ui->openSerialBtn, &QPushButton::clicked, this, &MainWindow::openPort);
    /* 显示串口数据 */
    connect(&this->serialPortUsing, &QSerialPort::readyRead , this, &MainWindow::displayData);
    /* 发送串口数据 */
    connect(ui->sendDataBtn, &QPushButton::clicked, this, &MainWindow::sendData);
}

/*刷新串口处理函数*/
void MainWindow::refreshPort()
{
    qDebug() << "刷新串口";
    /*清除comboxBox的内容,防止显示重复的串口*/
    ui->displayPortComboBox->clear();

    /* 读取可以使用的串口*/
    this->avaiPortsList = QSerialPortInfo::availablePorts();
    /* 提取串口个数*/
    int avaiPortNum = avaiPortsList.length();

    /*逐个显示*/
    for(int i = 0; i < avaiPortNum; i++)
    {
        ui->displayPortComboBox->addItem(this->avaiPortsList[i].portName());
    }
}

/*打开串口处理函数*/
void MainWindow::openPort()
{
    if(!this->isOpenSerial)
    {
        /*读取当前的波特率和端口号*/
        qDebug() << "打开串口号:"<< ui->displayPortComboBox->currentText()<<"波特率:"<<ui->baudComboBox->currentText().toInt();

        /* 获取串口序号和波特率序号 */

        /*设置当前串口号*/
        int displayPortComboBoxCurrIndex = ui->displayPortComboBox->currentIndex();
        this->serialPortInfoUsing = this->avaiPortsList[displayPortComboBoxCurrIndex];
        this->serialPortUsing.setPort(this->serialPortInfoUsing);
        /*设置波特率*/
        this->serialPortUsing.setBaudRate(ui->baudComboBox->currentText().toInt());
        /*设置数据位:8位*/
        this->serialPortUsing.setDataBits(QSerialPort::Data8);
        /*设置停止位: 1位*/
        this->serialPortUsing.setStopBits(QSerialPort::OneStop);
        /*设置校验位: 无校验*/
        this->serialPortUsing.setParity(QSerialPort::NoParity);
        /*设置流控制: 无硬件流控制*/
        this->serialPortUsing.setFlowControl(QSerialPort::NoFlowControl);
        /*打开串口*/
        if(this->serialPortUsing.open(QIODevice::ReadWrite))
        {
            qDebug() << "打开串口成功!";
            this->isOpenSerial = true;
            ui->openSerialBtn->setText("关闭串口");
        }
        else
        {
            qDebug() << "打开串口失败!";
        }
    }
    else
    {
        qDebug() << "关闭串口";
        this->isOpenSerial = false;
        this->serialPortUsing.close();
        ui->openSerialBtn->setText("打开串口");
    }
}

/*显示串口数据函数*/
void MainWindow::displayData()
{
    QByteArray rx_data;
    rx_data = this->serialPortUsing.readAll();

    QString str = QString::fromLocal8Bit(rx_data);

    qDebug() << str;
    rx_data.clear();
}

/*发送串口数据函数*/
void MainWindow::sendData()
{
    this->serialPortUsing.write("hello world!\r\n");
}

MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    /* 定义可用端口列表变量*/
    QList<QSerialPortInfo> avaiPortsList;
    /* 定义波特率列表*/
    QStringList BaudList;
    /* 定义正在使用的串口对象*/
    QSerialPort serialPortUsing;
    /* 定义正在使用的串口信息对象*/
    QSerialPortInfo serialPortInfoUsing;
    /* 定义是否打开串口标志位 */
    bool isOpenSerial = false;
    /*刷新串口信号*/
    void refreshPort(void);
    /*打开串口信号*/
    void openPort(void);
    /*显示串口数据*/
    void displayData(void);
    /*发送串口数据*/
    void sendData(void);
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
  • 5
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零涂

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值