您的位置:首页 > 编程语言 > Qt开发

QT5串口编写简单的上位机

2017-05-23 14:03 507 查看
本文转自:http://blog.csdn.net/u014695839/article/details/50611549

最近在学习嵌入式,而上位机又是一个不可缺少的工具,于是就开始接触QT,学习编写上位机。刚开始的时候什么都不懂,发现http://www.devbean.net/2012/08/qt-study-road-2-catelog/这里有比较好的入门教程。学习了前面部分(我只看到了事件...),对QT有了大概的了解后,就开始在网上寻找上位机的编写方法。通过好几天的学习,终于写出了一个用于串口通信的上位机。下面开始介绍串口类的使用。

首先,QT5是自带QSerialPort这个类的,使用时需要在pro文件里面添加一行:

QT       += serialport
然后直接引用头文件就可以使用了。

[cpp] view
plain copy

#include <QtSerialPort/QSerialPort>  

#include <QtSerialPort/QSerialPortInfo>  

QSerialPort:提供访问串口的功能 

QSerialPortInfo:提供系统中存在的串口的信息
接下来需要创建一个QSerialPort的对象,对串口的名称、波特率、数据位、校验位、停止位等参数进行设置,然后才进行串口读写操作。
大概总结了一下,设置、读、写的过程。
一、设置(举例):

[cpp] view
plain copy

QSerialPort *serial = new QSerialPort;  

//设置串口名  

serial->setPortName(name);  

//打开串口  

serial->open(QIODevice::ReadWrite);  

//设置波特率  

serial->setBaudRate(BaudRate);  

//设置数据位数  

serial->setDataBits(QSerialPort::Data8);  

 //设置奇偶校验  

 serial->setParity(QSerialPort::NoParity);   

//设置停止位  

serial->setStopBits(QSerialPort::OneStop);  

//设置流控制  

serial->setFlowControl(QSerialPort::NoFlowControl);  

这里设置了串口名为name,打开串口并设置为可读可写,波特率为BaudRate,数据位为8位,没有奇偶校验位,停止位为1位,没有流控制。设置完这些就能进行读写操作了。作为一名新手,发现遇到不懂得可以在QtCreator里面可以选择关键字,按F1打开文档看类、函数等数据的手册。

二、读取数据

[cpp] view
plain copy

void MainWindow::Read_Data()  

{  

    QByteArray buf;  

    buf = serial->readAll();  

}  

当串口收到数据并且接收完毕后,会发出一个readyRead()的信号,因此只需要编写一个槽函数Read_Data(),设置信号槽,并在槽函数中使用readAll()把收到的数据读到buf中。

三、发送数据

[cpp] view
plain copy

serial->write(data);  

使用write函数便可以把字符串data一个个字节发送出去。

使用串口就只需以上步骤,使用完后只需要执行

[cpp] view
plain copy

serial->close();  

就可以关闭串口了。

我使用了ui界面设计来编写上位机的,界面如下:



代码如下:

[cpp] view
plain copy

//mianwindow.h  

#ifndef MAINWINDOW_H  

#define MAINWINDOW_H  

#include <QMainWindow>  

#include <QDebug>  

#include <QtSerialPort/QSerialPort>  

#include <QtSerialPort/QSerialPortInfo>  

namespace Ui {  

class MainWindow;  

}  

class MainWindow : public QMainWindow  

{  

    Q_OBJECT  

public:  

    explicit MainWindow(QWidget *parent = 0);  

    ~MainWindow();  

private slots:  

    void on_clearButton_clicked();  

    void on_sendButton_clicked();  

    void on_openButton_clicked();  

    void Read_Data();  

private:  

    Ui::MainWindow *ui;  

    QSerialPort *serial;  

};  

#endif // MAINWINDOW_H  

[cpp] view
plain copy

//mainwindow.c  

#include "mainwindow.h"  

#include "ui_mainwindow.h"  

  

MainWindow::MainWindow(QWidget *parent) :  

    QMainWindow(parent),  

    ui(new Ui::MainWindow)  

{  

    ui->setupUi(this);  

    //查找可用的串口  

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())  

    {  

        QSerialPort serial;  

        serial.setPort(info);  

        if(serial.open(QIODevice::ReadWrite))  

        {  

            ui->PortBox->addItem(serial.portName());  

            serial.close();  

        }  

    }  

    //设置波特率下拉菜单默认显示第三项  

    ui->BaudBox->setCurrentIndex(3);  

    //关闭发送按钮的使能  

    ui->sendButton->setEnabled(false);  

    qDebug() << tr("界面设定成功!");  

}  

MainWindow::~MainWindow()  

{  

    delete ui;  

}  

//清空接受窗口  

void MainWindow::on_clearButton_clicked()  

{  

    ui->textEdit->clear();  

}  

//发送数据  

void MainWindow::on_sendButton_clicked()  

{  

    serial->write(ui->textEdit_2->toPlainText().toLatin1());  

}  

//读取接收到的数据  

void MainWindow::Read_Data()  

{  

    QByteArray buf;  

    buf = serial->readAll();  

    if(!buf.isEmpty())  

    {  

        QString str = ui->textEdit->toPlainText();  

        str+=tr(buf);  

        ui->textEdit->clear();  

        ui->textEdit->append(str);  

    }  

    buf.clear();  

}  

void MainWindow::on_openButton_clicked()  

{  

    if(ui->openButton->text()==tr("打开串口"))  

    {  

        serial = new QSerialPort;  

        //设置串口名  

        serial->setPortName(ui->PortBox->currentText());  

        //打开串口  

        serial->open(QIODevice::ReadWrite);  

        //设置波特率  

        serial->setBaudRate(ui->BaudBox->currentText().toInt());  

        //设置数据位数  

        switch(ui->BitNumBox->currentIndex())  

        {  

        case 8: serial->setDataBits(QSerialPort::Data8); break;  

        default: break;  

        }  

        //设置奇偶校验  

        switch(ui->ParityBox->currentIndex())  

        {  

        case 0: serial->setParity(QSerialPort::NoParity); break;  

        default: break;  

        }  

        //设置停止位  

        switch(ui->StopBox->currentIndex())  

        {  

        case 1: serial->setStopBits(QSerialPort::OneStop); break;  

        case 2: serial->setStopBits(QSerialPort::TwoStop); break;  

        default: break;  

        }  

        //设置流控制  

        serial->setFlowControl(QSerialPort::NoFlowControl);  

        //关闭设置菜单使能  

        ui->PortBox->setEnabled(false);  

        ui->BaudBox->setEnabled(false);  

        ui->BitNumBox->setEnabled(false);  

        ui->ParityBox->setEnabled(false);  

        ui->StopBox->setEnabled(false);  

        ui->openButton->setText(tr("关闭串口"));  

        ui->sendButton->setEnabled(true);  

        //连接信号槽  

        QObject::connect(serial, &QSerialPort::readyRead, this, &MainWindow::Read_Data);  

    }  

    else  

    {  

        //关闭串口  

        serial->clear();  

        serial->close();  

        serial->deleteLater();  

        //恢复设置使能  

        ui->PortBox->setEnabled(true);  

        ui->BaudBox->setEnabled(true);  

        ui->BitNumBox->setEnabled(true);  

        ui->ParityBox->setEnabled(true);  

        ui->StopBox->setEnabled(true);  

        ui->openButton->setText(tr("打开串口"));  

        ui->sendButton->setEnabled(false);  

    }  

}  

[cpp] view
plain copy

//main.c  

#include "mainwindow.h"  

#include <QApplication>  

int main(int argc, char *argv[])  

{  

    QApplication a(argc, argv);  

    MainWindow w;  

    w.show();  

    return a.exec();  

}  

工程文件在这里可以下载:

版本一:已经被下载很多次了,但因为评论里的小伙伴提出了一些小问题,已经修改更新并重新上传到版本二了

http://download.csdn.net/detail/u014695839/9423213

版本二:删除mythread.h和mythread.c以及代码里面多余的#include "mythread.h",把Read_Data()槽函数里的if(buf!=NULL)改成了if(!buf.isEmpty())

http://download.csdn.net/detail/u014695839/9763670

以上程序若有问题,大家及时提醒,我定会马上更正!
希望大家在学习过程中相互交流。如果文章有错误,欢迎大家指出!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: