欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt串口通信開發(fā)之QSerialPort模塊詳細(xì)使用方法與實例

 更新時間:2020年03月12日 14:35:10   作者:滄海一笑-dj  
這篇文章主要介紹了Qt串口通信開發(fā)之QSerialPort模塊詳細(xì)使用方法與實例,需要的朋友可以參考下

Qt串口通信基礎(chǔ)及名詞說明

串口通信(Serial Communications)的概念非常簡單,串口按位(bit)發(fā)送和接收字節(jié)。盡管比按字節(jié)(byte)的并行通信慢,但是串口可以在使用一根線發(fā)送數(shù)據(jù)的同時用另一根線接收數(shù)據(jù)。它很簡單并且能夠?qū)崿F(xiàn)遠(yuǎn)距離通信。比如IEEE488定義并行通行狀態(tài)時,規(guī)定設(shè)備線總長不得超過20米,并且任意兩個設(shè)備間的長度不得超過2米;

而對于串口而言,長度可達(dá)1200米。典型地,串口用于ASCII碼字符的傳輸。通信使用3根線完成,分別是地線、發(fā)送、接收。由于串口通信是異步的,端口能夠在一根線上發(fā)送數(shù)據(jù)同時在另一根線上接收數(shù)據(jù)。其他線用于握手,但不是必須的。串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶校驗。對于兩個進(jìn)行通信的端口,這些參數(shù)必須匹配。

波特率:

這是一個衡量符號傳輸速率的參數(shù)。指的是信號被調(diào)制以后在單位時間內(nèi)的變化,即單位時間內(nèi)載波參數(shù)變化的次數(shù),如每秒鐘傳送240個字符,而每個字符格式包含10位(1個起始位,1個停止位,8個數(shù)據(jù)位),這時的波特率為240Bd,比特率為10位*240個/秒=2400bps。一般調(diào)制速率大于波特率,比如曼徹斯特編碼)。通常電話線的波特率為14400,28800和36600。波特率可以遠(yuǎn)遠(yuǎn)大于這些值,但是波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信。

數(shù)據(jù)位:

這是衡量通信中實際數(shù)據(jù)位的參數(shù)。當(dāng)計算機(jī)發(fā)送一個信息包,實際的數(shù)據(jù)往往不會是8位的,標(biāo)準(zhǔn)的值是6、7和8位。如何設(shè)置取決于你想傳送的信息。比如,標(biāo)準(zhǔn)的ASCII碼是0~127(7位)。擴(kuò)展的ASCII碼是0~255(8位)。如果數(shù)據(jù)使用簡單的文本(標(biāo)準(zhǔn) ASCII碼),那么每個數(shù)據(jù)包使用7位數(shù)據(jù)。每個包是指一個字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗位。由于實際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語“包”指任何通信的情況。

停止位:

用于表示單個包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時的,并且每一個設(shè)備有其自己的時鐘,很可能在通信中兩臺設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計算機(jī)校正時鐘同步的機(jī)會。適用于停止位的位數(shù)越多,不同時鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時也越慢。

奇偶校驗位:

在串口通信中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。當(dāng)然沒有校驗位也是可以的。對于偶和奇校驗的情況,串口會設(shè)置校驗位(數(shù)據(jù)位后面的一位),用一個值確保傳輸?shù)臄?shù)據(jù)有偶個或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對于偶校驗,校驗位為0,保證邏輯高的位數(shù)是偶數(shù)個。如果是奇校驗,校驗位為1,這樣就有3個邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡單置位邏輯高或者邏輯低校驗。這樣使得接收設(shè)備能夠知道一個位的狀態(tài),有機(jī)會判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步。

Qt串口通信模塊QtSerialPort簡介

QtSerialPort模塊是QT5中附加模塊的一個模塊,為硬件和虛擬的串口提供統(tǒng)一的接口。

串口由于其簡單和可靠,目前在像嵌入式系統(tǒng)、機(jī)器人等工業(yè)中依舊用得很多。使用QtSerialPort模塊,開發(fā)者可以大大縮短開發(fā)串口相關(guān)的應(yīng)用程的周期。

Qt SerialPort提供了基本的功能,包括配置、I/O操作、獲取和設(shè)置RS-232引腳的信號。

Qt SerialPort模塊暫不支持以下特性:

A、終端的特性,例如回顯,控制CR/LF等等

B、文本模式

C、讀或?qū)懖僮鞯某瑫r和延時配置

D、當(dāng)RS-232引腳信號變化通知

要在應(yīng)用程序中使用QtSerialPort,需要包括如下的聲明:

#include <QtSerialPort/QtSerialPort>

要鏈接QtSerialPort模塊,需要在.pro文件中添加如下內(nèi)容:

QT += serialport

QSerialPort提供了訪問串口的接口函數(shù)。使用輔助類QSerialPortInfo可以獲取可用的串口信息。將QSerialPortInfo輔助類對象做為參數(shù),使用setPort()或setPortName()函數(shù)可以設(shè)置要訪問的串口設(shè)備。

設(shè)置好端口后,可以使用open()函數(shù)以只讀、只寫或讀寫的模式打開使用。

注意,串口使用獨占方式打開。使用close()函數(shù)關(guān)閉串口并且取消IO操作。

串口成功打開后,QSerialPort會嘗試確定串口的當(dāng)前配置并初始化??梢允褂胹etBaudRate()、setDataBits()、setParity()、setStopBits()和setFlowControl()函數(shù)重新配置端口設(shè)置。

有一對名為QSerialPort::dataTerminalReady、QSerialPort::requestToSend的屬性

QSerialPort提供了中止正在調(diào)用線程直到信號觸發(fā)的一系列函數(shù)。這些函數(shù)用于阻塞串口。

waitForReadyRead():阻塞調(diào)用,直到有新的數(shù)據(jù)可讀

waitForBytesWritten():阻塞調(diào)用,直到數(shù)據(jù)以及寫入串口

阻塞串口編程與非阻塞串口編程完全不同。阻塞串口不會要求時間循環(huán)并且通常會簡化代碼。然而,在GUI程序中,為了避免凍結(jié)用戶界面,阻塞串口編程只能用于非GUI線程。

QSerialPort也能使用QTextStream和QDataStream的流操作符。在試圖使用流操作符>>讀時,需要確保有足夠可用的數(shù)據(jù)。

Qt串口通信模塊QSerialPort類成員函數(shù)

//構(gòu)造函數(shù)
QSerialPort::QSerialPort(QObject *parent = Q_NULLPTR)
QSerialPort::QSerialPort(const QString &name, QObject *parent = Q_NULLPTR)
QSerialPort::QSerialPort(const QSerialPortInfo &serialPortInfo, QObject *parent = Q_NULLPTR)
//如果當(dāng)前沒有數(shù)據(jù)可讀,返回true
[virtual] bool QSerialPort::atEnd() const
//波特率改變后,信號觸發(fā)
[signal] void QSerialPort::baudRateChanged(qint32 baudRate, QSerialPort::Directions directions)
//返回可讀數(shù)據(jù)的字節(jié)數(shù)
[virtual] qint64 QSerialPort::bytesAvailable() const
//返回可寫數(shù)據(jù)的字節(jié)數(shù)
[virtual] qint64 QSerialPort::bytesToWrite() const
//關(guān)閉串口
[virtual] void QSerialPort::close()
//設(shè)置串口端口信息為serialPortInfo
void QSerialPort::setPort(const QSerialPortInfo &serialPortInfo)
//設(shè)置串口名為name
void QSerialPort::setPortName(const QString &name)

Qt串口通信模塊QSerialPort簡單串口實例

main.cpp代碼

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 MainWindow w;
 w.show();
 return a.exec();
}

mainwindows.h代碼參考如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QList>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
 Q_OBJECT
public:
 explicit MainWindow(QWidget *parent = 0);
 ~MainWindow();
private slots:
 void on_btn_openConsole_clicked();
 void on_btn_send_clicked();
 void on_btn_clearRecv_clicked();
 void on_btn_clearSend_clicked();
 void readData();
private:
 Ui::MainWindow *ui;
 QSerialPort *serial;
};
#endif // MAINWINDOW_H

mainwindows.cpp代碼

#include "mainwindow.h"
#include "ui_mainwindow.h"
static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");
MainWindow::MainWindow(QWidget *parent) :
 QMainWindow(parent),
 ui(new Ui::MainWindow)
{
 ui->setupUi(this);
 serial = new QSerialPort;
 QString description;
 QString manufacturer;
 QString serialNumber;
 //獲取可以用的串口
 QList<QSerialPortInfo> serialPortInfos = QSerialPortInfo::availablePorts();
 //輸出當(dāng)前系統(tǒng)可以使用的串口個數(shù)
 qDebug() << "Total numbers of ports: " << serialPortInfos.count();
 //將所有可以使用的串口設(shè)備添加到ComboBox中
 for (const QSerialPortInfo &serialPortInfo : serialPortInfos)
 {
  QStringList list;
  description = serialPortInfo.description();
  manufacturer = serialPortInfo.manufacturer();
  serialNumber = serialPortInfo.serialNumber();
  list << serialPortInfo.portName()
    << (!description.isEmpty() ? description : blankString)
    << (!manufacturer.isEmpty() ? manufacturer : blankString)
    << (!serialNumber.isEmpty() ? serialNumber : blankString)
    << serialPortInfo.systemLocation()
    << (serialPortInfo.vendorIdentifier() ? QString::number(serialPortInfo.vendorIdentifier(), 16) : blankString)
    << (serialPortInfo.productIdentifier() ? QString::number(serialPortInfo.productIdentifier(), 16) : blankString);
  ui->comboBox_serialPort->addItem(list.first(), list);
 }
 ui->comboBox_serialPort->addItem(tr("custom"));
 //設(shè)置波特率
 ui->comboBox_baudRate->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
 ui->comboBox_baudRate->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
 ui->comboBox_baudRate->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
 ui->comboBox_baudRate->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
 ui->comboBox_baudRate->addItem(tr("Custom"));
 //設(shè)置數(shù)據(jù)位
 ui->comboBox_dataBits->addItem(QStringLiteral("5"), QSerialPort::Data5);
 ui->comboBox_dataBits->addItem(QStringLiteral("6"), QSerialPort::Data6);
 ui->comboBox_dataBits->addItem(QStringLiteral("7"), QSerialPort::Data7);
 ui->comboBox_dataBits->addItem(QStringLiteral("8"), QSerialPort::Data8);
 ui->comboBox_dataBits->setCurrentIndex(3);
 //設(shè)置奇偶校驗位
 ui->comboBox_parity->addItem(tr("None"), QSerialPort::NoParity);
 ui->comboBox_parity->addItem(tr("Even"), QSerialPort::EvenParity);
 ui->comboBox_parity->addItem(tr("Odd"), QSerialPort::OddParity);
 ui->comboBox_parity->addItem(tr("Mark"), QSerialPort::MarkParity);
 ui->comboBox_parity->addItem(tr("Space"), QSerialPort::SpaceParity);
 //設(shè)置停止位
 ui->comboBox_stopBit->addItem(QStringLiteral("1"), QSerialPort::OneStop);
 ui->comboBox_stopBit->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
 //添加流控
 ui->comboBox_flowBit->addItem(tr("None"), QSerialPort::NoFlowControl);
 ui->comboBox_flowBit->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
 ui->comboBox_flowBit->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
 //禁用發(fā)送按鈕
 ui->btn_send->setEnabled(false);
}
MainWindow::~MainWindow()
{
 //delete serial;
 delete ui;
}
//打開串口按鈕槽函數(shù)
void MainWindow::on_btn_openConsole_clicked()
{
 qDebug() << ui->btn_openConsole->text();
 if (ui->btn_openConsole->text() == tr("打開串口"))
 {
  //設(shè)置串口名字
  serial->setPortName(ui->comboBox_serialPort->currentText());
  //設(shè)置波特率
  serial->setBaudRate(ui->comboBox_baudRate->currentText().toInt());
  //設(shè)置數(shù)據(jù)位
  serial->setDataBits(QSerialPort::Data8);
  //設(shè)置奇偶校驗位
  serial->setParity(QSerialPort::NoParity);
  //設(shè)置停止位
  serial->setStopBits(QSerialPort::OneStop);
  //設(shè)置流控
  serial->setFlowControl(QSerialPort::NoFlowControl);
  //打開串口
  if (serial->open(QIODevice::ReadWrite))
  {
   ui->comboBox_baudRate->setEnabled(false);
   ui->comboBox_dataBits->setEnabled(false);
   ui->comboBox_flowBit->setEnabled(false);
   ui->comboBox_parity->setEnabled(false);
   ui->comboBox_serialPort->setEnabled(false);
   ui->comboBox_stopBit->setEnabled(false);
   ui->btn_send->setEnabled(true);
   ui->btn_openConsole->setText(tr("關(guān)閉串口"));
   //信號與槽函數(shù)關(guān)聯(lián)
   connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);
  }
 }
 else
 {
  //關(guān)閉串口
  //serial->clear();
  serial->close();
  //serial->deleteLater();
  //恢復(fù)設(shè)置功能
  ui->comboBox_baudRate->setEnabled(true);
  ui->comboBox_dataBits->setEnabled(true);
  ui->comboBox_flowBit->setEnabled(true);
  ui->comboBox_parity->setEnabled(true);
  ui->comboBox_serialPort->setEnabled(true);
  ui->comboBox_stopBit->setEnabled(true);
  ui->btn_openConsole->setText(tr("打開串口"));
  ui->btn_send->setEnabled(false);
 }
}
//發(fā)送數(shù)據(jù)槽函數(shù)
void MainWindow::on_btn_send_clicked()
{
 serial->write(ui->textEdit_send->toPlainText().toLatin1());
}
//清空接收數(shù)據(jù)槽函數(shù)
void MainWindow::on_btn_clearRecv_clicked()
{
 ui->textEdit_recv->clear();
}
//清空發(fā)送區(qū)槽函數(shù)
void MainWindow::on_btn_clearSend_clicked()
{
 ui->textEdit_send->clear();
}
void MainWindow::readData()
{
 QByteArray buf;
 qDebug() << "readData: " << endl;
 buf = serial->readAll();
 if (!buf.isEmpty())
 {
  QString str = ui->textEdit_recv->toPlainText();
  str += tr(buf);
  ui->textEdit_recv->clear();
  ui->textEdit_recv->append(str);
 }
}

圖形界面設(shè)計

圖形界面設(shè)計如圖所示:

圖形界面相關(guān)屬性設(shè)置:

測試結(jié)果

前提條件是需要串口硬件的支持

本文主要介紹了Qt串口通信模塊QSerialPort詳細(xì)使用方法與實例更多關(guān)于Qt串口通信的知識技巧請查看下面的相關(guān)鏈接

相關(guān)文章

  • C語言實戰(zhàn)之浪漫煙花表白程序代碼

    C語言實戰(zhàn)之浪漫煙花表白程序代碼

    這篇文章主要介紹了C語言實戰(zhàn)之浪漫煙花表白程序代碼,需要的朋友可以參考下
    2021-04-04
  • c++ minicsv庫的編譯錯誤與解決方案

    c++ minicsv庫的編譯錯誤與解決方案

    有一個項目需要寫csv文件以呈現(xiàn)數(shù)據(jù)。Github上有一個關(guān)于csv的輕量級讀寫庫minicsv,于是下載之。但是編譯example時出現(xiàn)了以下問題
    2016-11-11
  • C++實現(xiàn)LeetCode(70.爬樓梯問題)

    C++實現(xiàn)LeetCode(70.爬樓梯問題)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(70.爬樓梯問題),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算

    C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算

    這篇文章主要介紹了C語言科學(xué)計算入門之矩陣乘法的相關(guān)計算,文章中還介紹了矩陣相關(guān)的斯特拉森算法的實現(xiàn),需要的朋友可以參考下
    2015-12-12
  • c++回溯法解決1到9之間插入加減或空使運算結(jié)果為100

    c++回溯法解決1到9之間插入加減或空使運算結(jié)果為100

    編寫一個在1,2,…,9(順序不能變)數(shù)字之間插入+或-或什么都不插入,使得計算結(jié)果總是100的程序,并輸出所有的可能性。例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100
    2021-10-10
  • C++11/14 線程中使用Lambda函數(shù)的方法

    C++11/14 線程中使用Lambda函數(shù)的方法

    這篇文章主要介紹了C++11/14 線程中使用Lambda函數(shù)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • 利用C語言繪制一個正方體

    利用C語言繪制一個正方體

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言繪制一個正方體,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)和借鑒價值,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-01-01
  • VC程序設(shè)計中CreateProcess用法注意事項

    VC程序設(shè)計中CreateProcess用法注意事項

    這篇文章主要介紹了VC程序設(shè)計中CreateProcess用法注意事項,需要的朋友可以參考下
    2014-07-07
  • 詳解C++?左值引用與?const?關(guān)鍵字

    詳解C++?左值引用與?const?關(guān)鍵字

    這篇文章主要介紹了C++?左值引用與?const?關(guān)鍵字,左值引用是已定義的變量的別名,其主要用途是用作函數(shù)的形參,將?const?關(guān)鍵字用于左值引用時,其在初始化時可接受的賦值形式變得更加廣泛了,這里來總結(jié)一下,需要的朋友可以參考下
    2022-09-09
  • C語言中的const和free用法詳解

    C語言中的const和free用法詳解

    C語言中的const和C++中的const是有區(qū)別的,而且在使用VS編譯測試的時候,如果是C的話,請一定要建立一個后綴為C的文件,不要是CPP的文件。因為,兩個編譯器會有差別的。下面通過本文給大家分享C語言中的const和free用法,感興趣的朋友一起看看吧
    2017-04-04

最新評論