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
相关推荐
用户8055336980314 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner15 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00612 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术12 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript