Qt QSerialPort 串口通信程序

1.程序界面

在这里插入图片描述

2.程序功能

  • 16进制和非16进制的发送功能
  • 串口接收并以16进制显示功能
    待解决问题:
    一次性不能接收超过32个字节的数组

3.程序结构

在这里插入图片描述

4.主要代码

Qt_SerialPort.pro

#-------------------------------------------------
#
# Project created by QtCreator 2020-02-27T14:15:03
#
#-------------------------------------------------

QT       += core gui
QT       += serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Qt_USART
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 \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.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();
    QByteArray HexStringToByteArray(QString HexString);
    QString ByteArrayToHexString(QByteArray data);

private slots:
    void on_Button_detect_clicked();

    void on_Button_OpenPort_clicked();

    void on_pushButton_clear_rev_clicked();

    void on_pushButton_clear_send_clicked();

    void on_checkBox_hex_send_clicked(bool checked);

    void on_pushButton_serial_send_clicked();

    void on_checkBox_hex_display_clicked(bool checked);

    void serialPort_readyRead();

private:
    Ui::MainWindow *ui;
    QSerialPort serial;
};

#endif // MAINWINDOW_H

main.cpp

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("Qt串口通信例程");
    w.show();

    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //发送按键失能
    ui->pushButton_serial_send->setEnabled(false);
    //波特率默认选择下拉第三项:115200
    ui->Box_baudrate->setCurrentIndex(4);

    ui->checkBox_hex_display->setCheckState(Qt::Checked);
    ui->checkBox_hex_display->setEnabled(false);

    //连接信号和槽
    QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);
}

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

void MainWindow::on_Button_detect_clicked()
{
    ui->Box_portnum->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->Box_portnum->addItem(info.portName());
    }
}

void MainWindow::on_Button_OpenPort_clicked()
{
    if(ui->Button_OpenPort->text()==QString("打开串口"))
    {
        //设置串口名
        serial.setPortName(ui->Box_portnum->currentText());
        //设置波特率
        serial.setBaudRate(ui->Box_baudrate->currentText().toInt());
        //设置数据位数
        switch(ui->Box_dataBits->currentIndex())
        {
        case 8: serial.setDataBits(QSerialPort::Data8); break;
        default: break;
        }
        //设置奇偶校验
        switch(ui->Box_Parity->currentIndex())
        {
        case 0: serial.setParity(QSerialPort::NoParity); break;
        default: break;
        }
        //设置停止位
        switch(ui->Box_stopBits->currentIndex())
        {
        case 1: serial.setStopBits(QSerialPort::OneStop); break;
        case 2: serial.setStopBits(QSerialPort::TwoStop); break;
        default: break;
        }
        //设置流控制
        serial.setFlowControl(QSerialPort::NoFlowControl);

        //打开串口
        if(!serial.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL, "提示", "无法打开串口!");
            return;
        }

        //下拉菜单控件失能
        ui->Box_portnum->setEnabled(false);
        ui->Box_baudrate->setEnabled(false);
        ui->Box_dataBits->setEnabled(false);
        ui->Box_Parity->setEnabled(false);
        ui->Box_stopBits->setEnabled(false);

        ui->Button_OpenPort->setText(QString("关闭串口"));
        //发送按键使能
        ui->pushButton_serial_send->setEnabled(true);
    }
    else
    {
        //关闭串口
        serial.close();

        //下拉菜单控件使能
        ui->Box_portnum->setEnabled(true);
        ui->Box_baudrate->setEnabled(true);
        ui->Box_dataBits->setEnabled(true);
        ui->Box_Parity->setEnabled(true);
        ui->Box_stopBits->setEnabled(true);

        ui->Button_OpenPort->setText(QString("打开串口"));
        //发送按键失能
        ui->pushButton_serial_send->setEnabled(false);
    }
}

void MainWindow::on_pushButton_clear_rev_clicked()
{
    ui->textEdit_receive->clear();
}

void MainWindow::on_pushButton_clear_send_clicked()
{
    ui->textEdit_send->clear();
}

void MainWindow::on_checkBox_hex_display_clicked(bool checked)
{
    if(checked == true)
    {

    }
    else
    {

    }
}

void MainWindow::on_checkBox_hex_send_clicked(bool checked)
{
    if(checked == true)
    {

    }
    else
    {

    }
}

void MainWindow::on_pushButton_serial_send_clicked()
{
    //获取界面上的数据并转换成utf8格式的字节流
    QByteArray data;

    if(ui->checkBox_hex_send->isChecked() == true)
        data = HexStringToByteArray(ui->textEdit_send->toPlainText());
    else
        data = ui->textEdit_send->toPlainText().toUtf8();

    serial.write(data);
    /*也可以定长发送*/
    //serial.write((const char *)param_data, 16);
}

void MainWindow::serialPort_readyRead()
{
    //从接收缓冲区中读取数据
    QByteArray buffer = serial.readAll();

    //将16进制
    QString display_str = ByteArrayToHexString(buffer);

    //从界面中读取以前收到的数据
    QString recv = ui->textEdit_receive->toPlainText();
    recv += QString(display_str);
    //清空以前的显示
    ui->textEdit_receive->clear();
    //重新显示
    ui->textEdit_receive->append(recv);
}

/*
 * @breif 将16进制字符串转换为对应的字节序列
 */
QByteArray MainWindow::HexStringToByteArray(QString HexString)
{
    bool ok;
    QByteArray ret;
    HexString = HexString.trimmed();
    HexString = HexString.simplified();
    QStringList sl = HexString.split(" ");

    foreach (QString s, sl) {
        if(!s.isEmpty())
        {
            char c = s.toInt(&ok,16)&0xFF;
            if(ok){
                ret.append(c);
            }else{
                qDebug()<<"非法的16进制字符:"<<s;
                QMessageBox::warning(0,tr("错误:"),QString("非法的16进制字符: \"%1\"").arg(s));
            }
        }
    }
    //qDebug()<<ret;
    return ret;
}

/*
 * @breif 将字节序列转换为对应的16进制字符串
 */
QString MainWindow::ByteArrayToHexString(QByteArray data){
    QString ret(data.toHex().toUpper());
    int len = ret.length()/2;
    qDebug()<<len;
    for(int i=1;i<len;i++)
    {
        //qDebug()<<i;
        ret.insert(2*i+i-1," ");
    }

    return ret;
}



程序源码:https://download.csdn.net/download/u014779536/12195819

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt QSerialPort 是一个用于串口通信的类库,可以方便地实现串口数据的读取和写入。下面是一个基本的读取串口数据的示例代码: ```cpp #include <QCoreApplication> #include <QtSerialPort/QSerialPort> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建串口对象 QSerialPort serial; // 设置串口号 serial.setPortName("/dev/ttyUSB0"); // 设置波特率 serial.setBaudRate(QSerialPort::Baud9600); // 设置数据位 serial.setDataBits(QSerialPort::Data8); // 设置奇偶校验 serial.setParity(QSerialPort::NoParity); // 设置停止位 serial.setStopBits(QSerialPort::OneStop); // 设置流控制 serial.setFlowControl(QSerialPort::NoFlowControl); // 打开串口 if(!serial.open(QIODevice::ReadOnly)) { qDebug() << "无法打开串口"; return a.exec(); } // 读取串口数据 QByteArray buffer; while(serial.waitForReadyRead(100)) { buffer += serial.readAll(); } // 输出读取到的数据 qDebug() << buffer; // 关闭串口 serial.close(); return a.exec(); } ``` 在上面的代码中,我们首先创建了一个 QSerialPort 对象,并设置了串口号、波特率、数据位、奇偶校验、停止位和流控制等参数。然后使用 `open()` 函数打开串口,如果打开失败,则输出错误信息并退出程序。接着使用 `waitForReadyRead()` 函数等待串口有数据可读,然后使用 `readAll()` 函数读取数据并存储在 `buffer` 中。最后输出读取到的数据并关闭串口。 需要注意的是,在使用 `waitForReadyRead()` 函数时,我们设置了一个超时时间,如果在这个时间内没有数据可读,则函数会返回 false,退出循环。这个超时时间可以根据需要进行调整。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

超级D洋葱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值