串口通信(Serial Communications)的概念非常簡單,串口按位(bit)發(fā)送和接收字節(jié)。盡管比按字節(jié)(byte)的并行通信慢,但是串口可以在使用一根線發(fā)送數(shù)據(jù)的同時(shí)用另一根線接收數(shù)據(jù)。它很簡單并且能夠?qū)崿F(xiàn)遠(yuǎn)距離通信。比如IEEE488定義并行通行狀態(tài)時(shí),規(guī)定設(shè)備線總長不得超過20米,并且任意兩個(gè)設(shè)備間的長度不得超過2米;
成都創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、遷安網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、成都商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為遷安等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
而對于串口而言,長度可達(dá)1200米。典型地,串口用于ASCII碼字符的傳輸。通信使用3根線完成,分別是地線、發(fā)送、接收。由于串口通信是異步的,端口能夠在一根線上發(fā)送數(shù)據(jù)同時(shí)在另一根線上接收數(shù)據(jù)。其他線用于握手,但不是必須的。串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶校驗(yàn)。對于兩個(gè)進(jìn)行通信的端口,這些參數(shù)必須匹配。
這是一個(gè)衡量符號(hào)傳輸速率的參數(shù)。指的是信號(hào)被調(diào)制以后在單位時(shí)間內(nèi)的變化,即單位時(shí)間內(nèi)載波參數(shù)變化的次數(shù),如每秒鐘傳送240個(gè)字符,而每個(gè)字符格式包含10位(1個(gè)起始位,1個(gè)停止位,8個(gè)數(shù)據(jù)位),這時(shí)的波特率為240Bd,比特率為10位*240個(gè)/秒=2400bps。一般調(diào)制速率大于波特率,比如曼徹斯特編碼)。通常電話線的波特率為14400,28800和36600。波特率可以遠(yuǎn)遠(yuǎn)大于這些值,但是波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信。
這是衡量通信中實(shí)際數(shù)據(jù)位的參數(shù)。當(dāng)計(jì)算機(jī)發(fā)送一個(gè)信息包,實(shí)際的數(shù)據(jù)往往不會(huì)是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碼),那么每個(gè)數(shù)據(jù)包使用7位數(shù)據(jù)。每個(gè)包是指一個(gè)字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗(yàn)位。由于實(shí)際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語“包”指任何通信的情況。
用于表示單個(gè)包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時(shí)的,并且每一個(gè)設(shè)備有其自己的時(shí)鐘,很可能在通信中兩臺(tái)設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計(jì)算機(jī)校正時(shí)鐘同步的機(jī)會(huì)。適用于停止位的位數(shù)越多,不同時(shí)鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時(shí)也越慢。
在串口通信中一種簡單的檢錯(cuò)方式。有四種檢錯(cuò)方式:偶、奇、高和低。當(dāng)然沒有校驗(yàn)位也是可以的。對于偶和奇校驗(yàn)的情況,串口會(huì)設(shè)置校驗(yàn)位(數(shù)據(jù)位后面的一位),用一個(gè)值確保傳輸?shù)臄?shù)據(jù)有偶個(gè)或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對于偶校驗(yàn),校驗(yàn)位為0,保證邏輯高的位數(shù)是偶數(shù)個(gè)。如果是奇校驗(yàn),校驗(yàn)位為1,這樣就有3個(gè)邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡單置位邏輯高或者邏輯低校驗(yàn)。這樣使得接收設(shè)備能夠知道一個(gè)位的狀態(tài),有機(jī)會(huì)判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步。
QtSerialPort模塊是QT5中附加模塊的一個(gè)模塊,為硬件和虛擬的串口提供統(tǒng)一的接口。
串口由于其簡單和可靠,目前在像嵌入式系統(tǒng)、機(jī)器人等工業(yè)中依舊用得很多。使用QtSerialPort模塊,開發(fā)者可以大大縮短開發(fā)串口相關(guān)的應(yīng)用程的周期。
Qt SerialPort提供了基本的功能,包括配置、I/O操作、獲取和設(shè)置RS-232引腳的信號(hào)。
Qt SerialPort模塊暫不支持以下特性:
A、終端的特性,例如回顯,控制CR/LF等等
B、文本模式
C、讀或?qū)懖僮鞯某瑫r(shí)和延時(shí)配置
D、當(dāng)RS-232引腳信號(hào)變化通知
要在應(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ù)以只讀、只寫或讀寫的模式打開使用。
注意,串口使用獨(dú)占方式打開。使用close()函數(shù)關(guān)閉串口并且取消IO操作。
串口成功打開后,QSerialPort會(huì)嘗試確定串口的當(dāng)前配置并初始化??梢允褂胹etBaudRate()、setDataBits()、setParity()、setStopBits()和setFlowControl()函數(shù)重新配置端口設(shè)置。
有一對名為QSerialPort::dataTerminalReady、QSerialPort::requestToSend的屬性
QSerialPort提供了中止正在調(diào)用線程直到信號(hào)觸發(fā)的一系列函數(shù)。這些函數(shù)用于阻塞串口。
waitForReadyRead():阻塞調(diào)用,直到有新的數(shù)據(jù)可讀
waitForBytesWritten():阻塞調(diào)用,直到數(shù)據(jù)以及寫入串口
阻塞串口編程與非阻塞串口編程完全不同。阻塞串口不會(huì)要求時(shí)間循環(huán)并且通常會(huì)簡化代碼。然而,在GUI程序中,為了避免凍結(jié)用戶界面,阻塞串口編程只能用于非GUI線程。
QSerialPort也能使用QTextStream和QDataStream的流操作符。在試圖使用流操作符>>讀時(shí),需要確保有足夠可用的數(shù)據(jù)。
//構(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 //波特率改變后,信號(hào)觸發(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)
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)可以使用的串口個(gè)數(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è)置奇偶校驗(yàn)位 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è)置奇偶校驗(yàn)位 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)閉串口")); //信號(hào)與槽函數(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è)計(jì)如圖所示:
圖形界面相關(guān)屬性設(shè)置:
前提條件是需要串口硬件的支持
本文主要介紹了Qt串口通信模塊QSerialPort詳細(xì)使用方法與實(shí)例更多關(guān)于Qt串口通信的知識(shí)技巧請查看下面的相關(guān)鏈接
標(biāo)題名稱:Qt串口通信開發(fā)之QSerialPort模塊詳細(xì)使用方法與實(shí)例
當(dāng)前路徑:http://aaarwkj.com/article10/igjdgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、定制網(wǎng)站、響應(yīng)式網(wǎng)站、網(wǎng)站策劃、外貿(mào)建站、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)