使用QT实现串口通信

目录

前言

一、环境配置

二、QT代码编写

三、实验现象

​编辑

总结



前言

        串口通信最重要的点就是所用到的端口,数据位数,波特率,校验位以及停止位。关于理论知识就不解释,直接给代码。

一、环境配置

        因为没有实物进行实验,我们可以下载虚拟串口来模拟。

 这就相当于多出了COM1和COM2两根线,然后用串口调试助手和QT分别连接其中一个就可以实现串口通信了

二、QT代码编写

UI设计如下 

widget.cpp

#include "widget.h"
#include "ui_widget.h"

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

    SerialPortInit();
}

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

void Widget::SerialPortInit()
{
    serial = new QSerialPort;
    // 获取计算机中有效的端口号,然后将端口号的名称给端口选择控件
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        serial->setPort(info);                      // 在对象中设置串口
        if(serial->open(QIODevice::ReadWrite))      // 以读写方式打开串口
        {
            ui->serialComboBox->addItem(info.portName());  // 添加计算机中的端口
            serial->close();                        // 关闭
        } else
        {
            qDebug() << "串口打开失败,请重试";
        }
    }
    // 参数配置
    // 波特率,波特率默认选择115200 ,禁止用户点击
    ui->baudComboBox->addItem("115200");
    serial->setBaudRate(QSerialPort::Baud115200);
    ui->baudComboBox->setDisabled(true);

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

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

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

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

    // 刷新串口
    RefreshSerialPort(0);

    // 信号
    connect(serial,&QSerialPort::readyRead,this,&Widget::DataReceived);      // 接收数据
    connect(ui->sendPushButton,&QPushButton::clicked,this,&Widget::DataSend); // 发送数据
}

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

// 接收数据,使用read () / readLine () / readAll ()
void Widget::DataReceived()
{
    char BUF[512] = {0};                                       // 存储转换类型后的数据
    QByteArray data = serial->readAll();                      // 读取数据

    if(!data.isEmpty())                                 // 接收到数据
    {
        QString str = ui->recvTextEdit->toPlainText();  // 返回纯文本
        str += tr(data);                         // 数据是一行一行传送的,要保存所有数据
        ui->recvTextEdit->clear();                      // 清空之前的数据
        ui->recvTextEdit->append(str);                  // 将数据放入控件中
        qDebug() << "str info: " << ui->recvTextEdit->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->sendTextEdit->toPlainText().toLatin1());      // 串口发送数据
}

void Widget::on_openPushButton_clicked()
{
    if(serial->isOpen())                                  // 如果串口打开了,先给他关闭
    {
        serial->clear();
        serial->close();
        // 关闭状态,按钮显示“打开串口”
        ui->openPushButton->setText("打开串口");
        // 关闭状态,允许用户操作
        ui->baudComboBox->setDisabled(false);
        ui->crcComboBox->setDisabled(false);
        ui->dataComboBox->setDisabled(false);
        ui->stopComboBox->setDisabled(false);
        ui->controlComboBox->setDisabled(false);
        // 禁止操作“发送字符操作”
//        ui->SendWordOrder->setDisabled(true);
        ui->sendPushButton->setDisabled(true);
        ui->status_Label->setText("未连接");
        // 清空数据
        ui->recvTextEdit->clear();
        ui->sendTextEdit->clear();
    }
    else                                             // 如果串口关闭了,先给他打开
    {
        //当前选择的串口名字
        serial->setPortName(ui->serialComboBox->currentText());
        //用ReadWrite 的模式尝试打开串口,无法收发数据时,发出警告
        if(!serial->open(QIODevice::ReadWrite))
        {
            QMessageBox::warning(this,tr("提示"),tr("串口打开失败!"),QMessageBox::Ok);
            return;
         }
        // 打开状态,按钮显示“关闭串口”
        ui->openPushButton->setText("关闭串口");
        // 打开状态,禁止用户操作
        ui->baudComboBox->setDisabled(true);
        ui->crcComboBox->setDisabled(true);
        ui->dataComboBox->setDisabled(true);
        ui->stopComboBox->setDisabled(true);
        ui->controlComboBox->setDisabled(true);
        // 允许操作“发送字符操作”
//        ui->SendWordOrder->setDisabled(false);
        ui->sendPushButton->setDisabled(false);
        ui->status_Label->setText("已连接");
    }

}


//清除接收框中的内容
void Widget::on_clearRecvPushButton_clicked()
{
    ui->recvTextEdit->clear();
}

//清除发送框中的内容
void Widget::on_clearSendPushButton_clicked()
{
    ui->sendTextEdit->clear();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

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


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();

private slots:
    void on_openPushButton_clicked();

    void on_clearRecvPushButton_clicked();

    void on_clearSendPushButton_clicked();

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

};

#endif // WIDGET_H

三、实验现象

总结

        只是简单的实现了串口之间的通信,像设置波特率、选择串口、中文显示、HEX显示等都没有实现,有兴趣可以自己查阅资料进行设计。

链接:https://pan.baidu.com/s/1EJsu8QuWWI1VAqoIAnxD2A?pwd=zxn6 
提取码:zxn6

  • 6
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hard-coding

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

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

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

打赏作者

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

抵扣说明:

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

余额充值