Qt串口通信【一篇到底,代码详解】

在实现串口通信之前,需要先把ARM相关基础实现完成,这里我给出一个音乐播放案例,Qt源代码如下:

ui设计(注:UI设计根据自己linux在板子上的代码进行样式开发需要一一对应,这里我用的板子是三星的开发板)

在这里插入图片描述

widget.h源码如下:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
// 引入串口通信的两个头文件(第一步)
#include <QtSerialPort/QSerialPort>         // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    //串口功能
    void SerialPortInit(); //串口初始化函数
    void RefreshSerialPort(int index);// 刷新串口

private slots:
    void DataReceived(); //接收数据
    void DataSend(); //发送数据
    void LED(bool changeColor);
private slots:
    //点击发送 接收数据
    void on_SendEditBtn1_clicked();

    void on_SendEditBtn2_clicked();

    void on_SendEditBtn3_clicked();



    void on_ClearButton_clicked(); //清空所有的#

    void on_OpenSerialButton_clicked();//串口开关

    void on_ClearShowButton_clicked();//清空接收到的数据

    void on_SendEditBtn4_clicked();

    void on_SendEditBtn5_clicked();

    void on_SendEditBtn6_clicked();

    void on_SendEditBtn7_clicked();

    void on_SendEditBtn8_clicked();

    void on_SendEditBtn9_clicked();

private:
    Ui::Widget *ui;
    QSerialPort *serial;
    QStringList baudList; //波特率
    QStringList parityList; //校验位
    QStringList dataBitsList;//数据位
    QStringList stopBitsList; //停止位
    QStringList flowControlList; //控制流
};

#endif // WIDGET_H

widget.cpp源码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMessageBox>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    SerialPortInit();
}

Widget::~Widget()
{
    delete ui;
}
//串口进行初始化
void Widget::SerialPortInit()
{
    this->serial = new QSerialPort; //申请内存设置父对象
    // 获取计算机中有效的端口号COM4,然后将端口号的名称给端口选择控件
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
                serial->setPort(info);            // 在对象中设置串口
                if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
                {
                    ui->PortBox->addItem(info.portName());  // 添加计算机中的端口
                    serial->close();                        // 关闭
                } else
                {
                    qDebug() << "串口打开失败,请重试";
                }

    }
    // 参数配置
        // 波特率,波特率默认选择115200 ,禁止用户点击
        ui->BaudBox->addItem("115200");
        serial->setBaudRate(QSerialPort::Baud115200);
        ui->BaudBox->setDisabled(true);

        // 校验,校验默认选择无
        ui->ParityBox->addItem("无");
        serial->setParity(QSerialPort::NoParity);

        // 数据位,数据位默认选择8位
        ui->BitBox->addItem("8");
        serial->setDataBits(QSerialPort::Data8);

        // 停止位,停止位默认选择1位
        ui->StopBox->addItem("1");
        serial->setStopBits(QSerialPort::OneStop);

        // 控制流,默认选择无
        ui->ControlBox->addItem("无");
        serial->setFlowControl(QSerialPort::NoFlowControl);

        // 刷新串口
        RefreshSerialPort(0);

        // 信号
        connect(this->serial,SIGNAL(readyRead()),this,SLOT(DataReceived()));      // 接收数据

        connect(ui->SendEditBtn1,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn2,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn3,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn4,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn5,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn6,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn7,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn8,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
        connect(ui->SendEditBtn9,SIGNAL(clicked()),this,SLOT(DataSend()));  // 发送数据
}

//刷新串口
void Widget::RefreshSerialPort(int index)
{
    QStringList portNameList;                                        // 存储所有串口名
        if(index != 0)
        {
            serial->setPortName(ui->PortBox->currentText());             //设置串口号
        }
        else
        {
            ui->PortBox->clear();                                        //关闭串口号
            ui->PortBox->addItem("刷新");                                //添加刷新
            foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口
            {
                portNameList.append(info.portName());
            }
            ui->PortBox->addItems(portNameList);
            ui->PortBox->setCurrentIndex(1);                             // 当前串口号为COM1
            serial->setPortName(ui->PortBox->currentText());             //设置串口号
       }

}
//发送和接收数据 read()/readline()/readAll()
void Widget::DataReceived()
{
    char BUF[512] = {0};// 存储转换类型后的数据
    QByteArray data = serial->readAll(); //读取数据
    if(!data.isEmpty()) //接收到数据
    {
        QString str = this->ui->DataReceived->toPlainText();//返回纯文本
        str += tr(data);// 数据是一行一行传送的,要保存所有数据
        ui->DataReceived->clear();                      // 清空之前的数据
        ui->DataReceived->append(str);                  // 将数据放入控件中
        qDebug() << "str info: " << ui->DataReceived->toPlainText();
        // 清除之前的数据,防止追加,因为每次获取的数据不一样
        int index = str.indexOf("\r\n");                // 找到,返回索引值,找不到,返回-1
        if(index != -1)
        {
             snprintf(BUF,500,"%s", str.left(index + 2).toUtf8().data()); // QString转为char * 类型
             qDebug() << "BUF info: " << BUF;        // 数据类型转换成功
             str.remove(0,index + 2);

             // 处理获取到的数据,将其放入对应的控件中
             // .....
        }


    }
}
//发送数据 write()
void Widget::DataSend()
{
    serial->write(ui->DataSend->toPlainText().toLatin1());      // 串口发送数据
}
// 点击发送后,获取串口信息并展示在接受控件中
void Widget::on_SendEditBtn1_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn1->text();               //获取发送框内容

    qDebug() << "SendEditBtn1 text: " << EditText;

    ui->DataSend->setText(EditText);                     //将文本内容放在发送栏中
}

void Widget::on_SendEditBtn2_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn2->text();               //获取发送框内容

    qDebug() << "SendEditBtn2 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn3_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn3->text();               //获取发送框内容

    qDebug() << "SendEditBtn3 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn4_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn4->text();               //获取发送框内容

    qDebug() << "SendEditBtn4 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn5_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn5->text();               //获取发送框内容

    qDebug() << "SendEditBtn5 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn6_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn6->text();               //获取发送框内容

    qDebug() << "SendEditBtn6 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn7_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn7->text();               //获取发送框内容

    qDebug() << "SendEditBtn7 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}

void Widget::on_SendEditBtn8_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn8->text();               //获取发送框内容

    qDebug() << "SendEditBtn8 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中


}

void Widget::on_SendEditBtn9_clicked()
{
    on_ClearButton_clicked();
    QString EditText = ui->SendEditBtn9->text();               //获取发送框内容

    qDebug() << "SendEditBtn9 text: " << EditText;

    ui->DataSend->append(EditText);                     //将文本内容放在发送栏中

}
//清空控件
void Widget::on_ClearButton_clicked()
{
    ui->DataSend->setText("");
}
//清空接收到的数据
void Widget::on_ClearShowButton_clicked()
{
    ui->DataReceived->setText("");
}

//串口开关
void Widget::on_OpenSerialButton_clicked()
{
    if(serial->isOpen())                                  // 如果串口打开了,先给他关闭
        {
            serial->clear();
            serial->close();
            // 关闭状态,按钮显示“打开串口”
            ui->OpenSerialButton->setText("打开串口");
            // 关闭状态,允许用户操作
            ui->BaudBox->setDisabled(false);
            ui->ParityBox->setDisabled(false);
            ui->BitBox->setDisabled(false);
            ui->StopBox->setDisabled(false);
            ui->ControlBox->setDisabled(false);
            // 关闭状态,颜色为绿色
            ui->OpenSerialButton->setStyleSheet("color: green;");
            // 关闭,显示灯为红色
            LED(true);
            // 清空数据
            ui->DataReceived->clear();
            ui->DataSend->clear();
        }
        else                                             // 如果串口关闭了,先给他打开
        {
            //当前选择的串口名字
            serial->setPortName(ui->PortBox->currentText());
            //用ReadWrite 的模式尝试打开串口,无法收发数据时,发出警告
            if(!serial->open(QIODevice::ReadWrite))
            {
                QMessageBox::warning(this,tr("提示"),tr("串口打开失败!"),QMessageBox::Ok);
                return;
             }
            // 打开状态,按钮显示“关闭串口”
            ui->OpenSerialButton->setText("关闭串口");
            // 打开状态,禁止用户操作
            ui->BaudBox->setDisabled(true);
            ui->ParityBox->setDisabled(true);
            ui->BitBox->setDisabled(true);
            ui->StopBox->setDisabled(true);
            ui->ControlBox->setDisabled(true);
            // 打开状态,颜色为红色
            ui->OpenSerialButton->setStyleSheet("color: red;");
            // 打开,显示灯为绿色
            LED(false);
        }

}
//显示灯颜色
void Widget::LED(bool changeColor)
{

    if(changeColor == false)
        {
            // 显示绿色
            ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
        }
        else
        {
            // 显示红色
            ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
        }

}


此项目还涵盖了ARM的部分内容,需要自己去编写,代码不难,在linux下进行编写,实现ARM里面的一个PWM即可,里面涵盖了一个蜂鸣器的调试,根据个人的不同情况进行编写即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值