Qt實踐(二)——實現串列埠通訊
阿新 • • 發佈:2018-12-13
如果用Qt寫程式作為上位機,然後通過和usb和下位機通訊的時候,就需要用到Qt中的串列埠通訊了。
使用Qt中的串列埠通訊的時候需要用到的兩個標頭檔案分別為:
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
除了加上面兩個標頭檔案之外,還需要在工程檔案中加下面一行程式碼:
QT += serialport
一般都需要先定義一個全域性的串列埠物件,在標頭檔案中新增上:
QSerialPort *serial;
一般來講Qt串列埠通訊需要經過7步:
1、設定串列埠名(如COM1):
serial = new QSerialPort;
serial->setPortName(ui->PortBox->currentText());
也可以用自動尋找可用串列埠的方法進行自動設定:
foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { QSerialPort serial; serial.setPort(info); if(serial.open(QIODevice::ReadWrite)) { ui->PortBox->addItem(serial.portName()); serial.close(); } }
2、開啟串列埠
serial->open(QIODevice::ReadWrite);
3、設定波特率(如115200)
serial->setBaudRate(QSerialPort::Baud115200);
4、設定資料位(如8)
serial->setDataBits(QSerialPort::Data8);//設定資料位8
5、設定校驗位(如0)
serial->setParity(QSerialPort::NoParity); //校驗位設定為0
6、設定停止位(如1)
serial->setStopBits(QSerialPort::OneStop);//停止位設定為1
7、設定流控制
serial->setFlowControl(QSerialPort::NoFlowControl);//設定為無流控制
下面是對資料的傳送和接收:
1、連線資料接收槽函式,下位機中一有資料傳送過來的時候就會響應這個槽函式
QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);
2、從上位機發送資料到下位機
serial->write(ui->textEdit_2->toPlainText().toLatin1());
下面是完整的工程檔案:
demo.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2018-10-01T15:23:39
#
#-------------------------------------------------
QT += core gui
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = demo
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
mainwindow.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_OpenSerialButton_clicked();
void ReadData();
void on_SendButton_clicked();
void on_ClearButton_clicked();
private:
Ui::MainWindow *ui;
QSerialPort *serial;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#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();
}
}
//設定波特率下拉選單預設顯示第0項
ui->BaudBox->setCurrentIndex(0);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_OpenSerialButton_clicked()
{
if(ui->OpenSerialButton->text() == tr("開啟串列埠"))
{
serial = new QSerialPort;
//設定串列埠名
serial->setPortName(ui->PortBox->currentText());
//開啟串列埠
serial->open(QIODevice::ReadWrite);
//設定波特率
serial->setBaudRate(QSerialPort::Baud115200);//設定波特率為115200
//設定資料位數
switch (ui->BitBox->currentIndex())
{
case 8:
serial->setDataBits(QSerialPort::Data8);//設定資料位8
break;
default:
break;
}
//設定校驗位
switch (ui->ParityBox->currentIndex())
{
case 0:
serial->setParity(QSerialPort::NoParity);
break;
default:
break;
}
//設定停止位
switch (ui->BitBox->currentIndex())
{
case 1:
serial->setStopBits(QSerialPort::OneStop);//停止位設定為1
break;
case 2:
serial->setStopBits(QSerialPort::TwoStop);
default:
break;
}
//設定流控制
serial->setFlowControl(QSerialPort::NoFlowControl);//設定為無流控制
//關閉設定選單使能
ui->PortBox->setEnabled(false);
ui->BaudBox->setEnabled(false);
ui->BitBox->setEnabled(false);
ui->ParityBox->setEnabled(false);
ui->StopBox->setEnabled(false);
ui->OpenSerialButton->setText(tr("關閉串列埠"));
//連線訊號槽
QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);
}
else
{
//關閉串列埠
serial->clear();
serial->close();
serial->deleteLater();
//恢復設定使能
ui->PortBox->setEnabled(true);
ui->BaudBox->setEnabled(true);
ui->BitBox->setEnabled(true);
ui->ParityBox->setEnabled(true);
ui->StopBox->setEnabled(true);
ui->OpenSerialButton->setText(tr("開啟串列埠"));
}
}
//讀取接收到的資訊
void MainWindow::ReadData()
{
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_SendButton_clicked()
{
serial->write(ui->textEdit_2->toPlainText().toLatin1());
}
void MainWindow::on_ClearButton_clicked()
{
ui->textEdit->clear();
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.ui(程式碼不能直接編輯,需要通過Ui介面來進行編輯):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>568</width>
<height>526</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="OpenSerialButton">
<property name="geometry">
<rect>
<x>90</x>
<y>400</y>
<width>111</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string>開啟串列埠</string>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>220</x>
<y>10</y>
<width>191</width>
<height>301</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="SendButton">
<property name="geometry">
<rect>
<x>430</x>
<y>340</y>
<width>131</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string>傳送</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>61</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>串列埠</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>71</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>資料位</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>190</y>
<width>71</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>校驗位</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>10</x>
<y>260</y>
<width>71</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>停止位</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>61</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>波特率</string>
</property>
</widget>
<widget class="QComboBox" name="PortBox">
<property name="geometry">
<rect>
<x>90</x>
<y>10</y>
<width>111</width>
<height>41</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="BaudBox">
<property name="geometry">
<rect>
<x>90</x>
<y>70</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
<item>
<property name="text">
<string>57600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="BitBox">
<property name="geometry">
<rect>
<x>90</x>
<y>130</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<item>
<property name="text">
<string>8</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="ParityBox">
<property name="geometry">
<rect>
<x>90</x>
<y>190</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<item>
<property name="text">
<string>0</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="StopBox">
<property name="geometry">
<rect>
<x>90</x>
<y>260</y>
<width>111</width>
<height>41</height>
</rect>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
</widget>
<widget class="QTextEdit" name="textEdit_2">
<property name="geometry">
<rect>
<x>220</x>
<y>340</y>
<width>191</width>
<height>61</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="ClearButton">
<property name="geometry">
<rect>
<x>90</x>
<y>320</y>
<width>111</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string>清空接收區</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>568</width>
<height>17</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
上面就是執行的結果。