QT(14)-UBUNTU下QT使用串口

1.环境配置

复制代码
sudo apt-get install build-essential
sudo apt-get install cmake qt5-default qtcreator
sudo apt-get install libqt5serialport5
sudo apt-get install libqt5serialport5-dev
sudo apt remove brltty

2.安装CH340驱动

复制代码
cd /lib/modules/$(uname -r)/kernel/drivers/usb/serial
sudo rm -rf ch341.ko

下载
http://www.wch.cn/download/CH341SER_LINUX_ZIP.html
解压
复制代码
uname -r
打开
https://elixir.bootlin.com/linux/v5.8/source/drivers/usb/serial/ch341.c
替换源码

make
sudo cp ch341.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial
cd /lib/modules/$(uname -r)/kernel/drivers/usb/serial

测试
sudo apt install cutecom
sudo cutecom

插拔USB执行dmesg会显示连接信息

3.QT源码

复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    customplot_init();
    serial_init();
}

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

void MainWindow::customplot_init()
{
    ui->customplot->clearGraphs();
    ui->customplot->addGraph();
    ui->customplot->graph(0)->setName("波形显示");

    //坐标轴使用时间刻度
    QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    timeTicker->setTimeFormat("%h:%m:%s");
    ui->customplot->xAxis->setTicker(timeTicker);
    ui->customplot->xAxis->setLabel("时间");//("时间(T)");
    ui->customplot->yAxis->setLabel("电压(V)");
    ui->customplot->legend->setVisible(true);
    //设置基本坐标轴(左侧Y轴和下方X轴)可拖动、可缩放、曲线可选、legend可选、设置伸缩比例,使所有图例可见
    ui->customplot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes |
                                      QCP::iSelectLegend | QCP::iSelectPlottables);
}

void MainWindow::serial_init()
{
    //读取串口信息
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        // 自动读取串口号添加到端口portBox中
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->portBox->addItem(info.portName());
            serial.close();
        }
    }
    QStringList baudList;   //波特率
    QStringList parityList; //校验位
    QStringList dataBitsList;   //数据位
    QStringList stopBitsList;   //停止位
    // 波特率    //波特率默认选择下拉第三项:9600
    baudList<<"1200"<<"2400"<<"4800"<<"9600"
           <<"14400"<<"19200"<<"38400"<<"56000"
          <<"57600"<<"115200";
    ui->rateBox->addItems(baudList);
    ui->rateBox->setCurrentIndex(3);
    // 校验      //校验默认选择无
    parityList<<"无"<<"奇"<<"偶";
    ui->checkBox->addItems(parityList);
    ui->checkBox->setCurrentIndex(0);
    // 数据位      //数据位默认选择8位
    dataBitsList<<"5"<<"6"<<"7"<<"8";
    ui->dataBox->addItems(dataBitsList);
    ui->dataBox->setCurrentIndex(3);
    // 停止位      //停止位默认选择1位
    stopBitsList<<"1"<<"2";
    ui->stopBox->addItems(stopBitsList);
    ui->stopBox->setCurrentIndex(0);
}

void MainWindow::on_searchBtn_clicked()
{
    ui->portBox->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {   //在portBox中显示可用串口
        ui->portBox->addItem(info.portName());
    }
}


void MainWindow::on_openBtn_clicked()
{
    // 打开串口
    if(ui->openBtn->text() == "打开串口")
    {
        SerialPort = new QSerialPort;
        // 设置串口号
        SerialPort->setPortName(ui->portBox->currentText());
        // 打开串口
        if(SerialPort->open(QIODevice::ReadWrite))
        {
            // 设置波特率
            SerialPort->setBaudRate(ui->rateBox->currentText().toInt());
            //设置数据位数
            switch(ui->dataBox->currentIndex())
            {
            case 5: SerialPort->setDataBits(QSerialPort::Data5); break;
            case 6: SerialPort->setDataBits(QSerialPort::Data6); break;
            case 7: SerialPort->setDataBits(QSerialPort::Data7); break;
            case 8: SerialPort->setDataBits(QSerialPort::Data8); break;
            default: break;
            }
            // 设置校验位
            //SerialPort->setParity(QSerialPort::NoParity);
            //设置奇偶校验
            switch(ui->checkBox->currentIndex())
            {
            case 0: SerialPort->setParity(QSerialPort::NoParity); break;
            case 1: SerialPort->setParity(QSerialPort::OddParity); break;
            case 2: SerialPort->setParity(QSerialPort::EvenParity); break;
            default: break;
            }
            // 设置流控制
            SerialPort->setFlowControl(QSerialPort::NoFlowControl);
            //设置停止位
            switch(ui->stopBox->currentIndex())
            {
            case 1: SerialPort->setStopBits(QSerialPort::OneStop); break;
            case 2: SerialPort->setStopBits(QSerialPort::TwoStop); break;
            default: break;
            }
        }
        //打开串口
        else
        {
            QMessageBox::about(NULL, "提示", "串口无法打开\r\n不存在或已被占用");
            return;
        }
        ui->openBtn->setText("关闭串口");
        //下拉菜单控件使能
        ui->portBox->setEnabled(false);
        ui->rateBox->setEnabled(false);
        ui->dataBox->setEnabled(false);
        ui->checkBox->setEnabled(false);
        ui->stopBox->setEnabled(false);
        //搜索串口按键使能
        ui->searchBtn->setEnabled(false);
        //发送按键使能
        ui->sendBox->setEnabled(true);

        connect(SerialPort,&QSerialPort::readyRead,this,&MainWindow::serial_Read);      // 接收数据
    }
    // 关闭串口
    else
    {
        SerialPort->close();
        ui->openBtn->setText("打开串口");
        //下拉按键使能
        ui->portBox->setEnabled(true);
        ui->rateBox->setEnabled(true);
        ui->dataBox->setEnabled(true);
        ui->checkBox->setEnabled(true);
        ui->stopBox->setEnabled(true);
        //搜索串口按键使能
        ui->searchBtn->setEnabled(true);
        //发送按键使能
        ui->sendBox->setEnabled(false);
    }
}

void MainWindow::serial_Read()
{
    QString buffer_1;
    //从缓冲区中读取数据
    QByteArray buffer = SerialPort->readAll();
    if(!buffer.isEmpty())//如果非空说明有数据接收
    {   //转换成16进制大写
        QString str=buffer.toHex().data();
        str=str.toUpper();
        //一个16进制占4位,8位为一字节,所以每两位16进制空一格
        for(int i=0;i<str.length();i+=2)
        {
               QString str_1 = str.mid (i,2);
               buffer_1 += str_1;
               buffer_1 += " ";
        }
    //读取之前显示数据
    QString receive = ui->receiveData->toPlainText();
    //清空显示
    ui->receiveData->clear();
    //重新显示
    if(ui->radioButton_3->isChecked()==0){
            receive += QString(buffer);
            ui->receiveData->append(receive);
            }//直接显示
    else    {
            receive += QString(buffer_1);
            ui->receiveData->append(receive);
            }//16进制显示
    }
    buffer.clear();
}


void MainWindow::on_sendBox_clicked()
{
    QByteArray Data_1;
    //获取输入窗口sendData的数据
    QString Data = ui->sendData->toPlainText();
    if(ui->radioButton->isChecked())       {Data+='\r';Data+='\n';}//插入换行
    if(ui->radioButton_2->isChecked()==0)    Data_1 = Data.toUtf8();//转换成utf8格式的字节流发送
    else        Data_1 = QByteArray::fromHex (Data.toLatin1().data());//按十六进制编码发送
    // 写入发送缓存区
    SerialPort->write(Data_1);

}


void MainWindow::on_pushButton_5_clicked()
{
    ui->receiveData->clear();
}


void MainWindow::on_pushButton_4_clicked()
{
    ui->sendData->clear();
}

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#pragma execution_character_set("utf-8")

#include <QMainWindow>
#include <QObject>
#include "qcustomplot.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void customplot_init();
    void serial_init();

private slots:
    void serial_Read();//串口数据读取显示
    void on_searchBtn_clicked();
    void on_openBtn_clicked();
    void on_pushButton_5_clicked();
    void on_pushButton_4_clicked();
    void on_sendBox_clicked();

private:
    Ui::MainWindow *ui;
    QSerialPort *SerialPort;

};
#endif // MAINWINDOW_H

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport serialport

CONFIG += c++17
RC_ICONS = favicon.ico

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    QCustomPlot/qcustomplot.cpp \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    QCustomPlot/qcustomplot.h \
    mainwindow.h

FORMS += \
    mainwindow.ui

INCLUDEPATH += QCustomPlot

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
相关推荐
Jun6261 小时前
QT(16)-云端版本管理
开发语言·qt
ggaofeng1 小时前
试用zeroclaw
java·开发语言
~|Bernard|1 小时前
关于go语言中二维切片的append操作陷阱
开发语言·后端·golang
c++之路1 小时前
C/C++ 全链路编译工具汇总
c语言·开发语言·c++
c238561 小时前
C++的IO流深入理解(下)
开发语言·c++
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第四章 Item 27 - 29)
开发语言·人工智能·经验分享·python·学习方法
简简单单lym1 小时前
WebRTC进阶--red+ulpfec深度解析3-FEC--冗余控制机制深度解析
开发语言·webrtc
凡人叶枫2 小时前
Effective C++ 条款02:宁可以编译器替换预处理器
java·linux·c语言·开发语言·c++