1. 程式人生 > >QT學習筆記——串列埠通訊

QT學習筆記——串列埠通訊

寫一個最簡單的串列埠助手。

QT5以後,編寫串列埠不需要藉助第三方庫了,可以說方便了不少。

先建立QT專案,在.pro檔案里加入下面這行程式碼,不然會沒有串列埠庫額昂你使用的

QT    += serialport

然後在標頭檔案mainwindows.h中加入標頭檔案

#include <QSerialPort>
#include <QSerialPortInfo>

其中QSerialPort是用來操作串列埠的,QSerialPortInfo提供串列埠資訊

接著建立一個串列埠例項

    QSerialPort *serial;

由於是做一個最簡單的串列埠助手,所以介面很簡潔,把波特率之類的都預設,只留了一個串列埠選擇,連線,清理和傳送。

串列埠選擇這裡可以直接去裝置管理器裡面檢視串列埠號,然後選擇預設的COM號進行連線,是如下操作

serial = new QSerialPort;
serial->setPortName(ui->comboBox->currentText());

也可以通過QSerialPort提供的功能,自動識別可利用的串列埠,並加入到comboBox。具體實現如下

void MainWindow::GetPort()
{
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->comboBox->addItem(serial.portName());
            serial.close();
        }
    }
}

然後設定串列埠的一系列引數,為了方便直接賦值

serial->setBaudRate(QSerialPort::Baud9600); //設定波特率
serial->setDataBits(QSerialPort::Data8); //設定資料位
serial->setParity(QSerialPort::NoParity); //設定校驗位
serial->setStopBits(QSerialPort::OneStop); //設定停止位
serial->setFlowControl(QSerialPort::NoFlowControl); //設定流控制

然後就是資料的接收和傳送了

從上位機發送到下位機很直接

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

上位機接收下位機的資料分兩步走

先寫好資料處理函式,讓接收到的資料在顯示框接在已有的資料顯示

void MainWindow::ReadData()
{
    QByteArray buf;
    buf = serial->readAll();
    if(!buf.isEmpty())
    {
        QString str = ui->textBrowser->toPlainText();
        str += tr(buf);
        ui->textBrowser->clear();
        ui->textBrowser->append(str);
    }
    buf.clear();
}

然後將訊號與槽函式連線,當串列埠接收到資料就呼叫資料處理的函式

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

然後,一個最簡單的串列埠助手就寫完了。

用虛擬串列埠做測試

貼出mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

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

void MainWindow::ReadData()
{
    QByteArray buf;
    buf = serial->readAll();
    if(!buf.isEmpty())
    {
        QString str = ui->textBrowser->toPlainText();
        str += tr(buf);
        ui->textBrowser->clear();
        ui->textBrowser->append(str);
    }
    buf.clear();
}

void MainWindow::GetPort()
{
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->comboBox->addItem(serial.portName());
            serial.close();
        }
    }
}

void MainWindow::on_pushButton_Send_clicked()
{
    serial->write(ui->textEdit->toPlainText().toLatin1());
}

void MainWindow::on_pushButton_Clear_clicked()
{
    ui->textBrowser->clear();
    ui->textEdit->clear();
}

void MainWindow::on_pushButton_clicked()
{
    if(ui->pushButton->text() == tr("連線"))
    {
        serial = new QSerialPort;
        serial->setPortName(ui->comboBox->currentText());
        serial->open(QIODevice::ReadWrite);
        serial->setBaudRate(QSerialPort::Baud9600);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        ui->pushButton->setText(tr("斷開"));

        connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReadData);
    }
    else
    {
        serial->clear();
        serial->close();
        serial->deleteLater();

        ui->pushButton->setText(tr("連線"));
    }
}