要實現串口通信,需要知道串口通信需要的信息
主要參數有:波特率、校驗位、數據位、停止位、控制流
主要操作有:串口的打開和關閉、刷新設備串口、接發數據、開關顯示燈等。
實現效果如圖:
界面設計如下:
每個控件類名如下:
LED燈是QLable控件,設置它的長寬都是24px,然后鼠標右擊,選擇“樣式表”,在樣式表中添加代碼。
附贈完整源碼
第一步:在頭文件中引入 QtSerialPort 類的兩個頭文件(必須引入)
// 引入串口通信的兩個頭文件(第一步)
#include // 提供訪問串口的功能
#include // 提供系統中存在的串口信
第二步:在工程文件中添加以下代碼
# 引入串口工程類型(第二步)
QT += serialport
第三步:在頭文件中定義全局的串口對象
QSerialPort *serial; // 定義全局的串口對象(第三步
第四步:參數設置,在頭文件中定義初始化參數的函數和參數變量名,在.cpp文件中實現函數
public:
void SerialPortInit(); // 串口初始化(參數配置)
private:
// 參數配置
QStringList baudList; //波特率
QStringList parityList; //校驗位
QStringList dataBitsList; //數據位
QStringList stopBitsList; //停止位
QStringList flowControlList; //控制流
// 串口初始化(參數配置)
void MainWindow::SerialPortInit()
{
serial = new QSerialPort; //申請內存,并設置父對象
// 獲取計算機中有效的端口號,然后將端口號的名稱給端口選擇控件
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
serial->setPort(info); // 在對象中設置串口
if(serial->open(QIODevice::ReadWrite)) // 以讀寫方式打開串口
{
ui->PortBox->addItem(info.portName()); // 添加計算機中的端口
serial->close(); // 關閉
} else
{
qDebug() << "串口打開失敗,請重試";
}
}
// 參數配置
// 波特率,波特率默認選擇57600 ,禁止用戶點擊
ui->BaudBox->addItem("57600");
serial->setBaudRate(QSerialPort::Baud57600);
ui->BaudBox->setDisabled(true);
// 校驗,校驗默認選擇無
ui->ParityBox->addItem("無");
serial->setParity(QSerialPort::NoParity);
// 數據位,數據位默認選擇8位
ui->BitBox->addItem("8");
serial->setDataBits(QSerialPort::Data8);
// 停止位,停止位默認選擇1位
ui->StopBox->addItem("1");
serial->setStopBits(QSerialPort::OneStop);
// 控制流,默認選擇無
ui->ControlBox->addItem("無");
serial->setFlowControl(QSerialPort::NoFlowControl);
// 刷新串口
RefreshSerialPort(0);
// 信號
connect(serial,&QSerialPort::readyRead,this,&MainWindow::DataReceived); // 接收數據
connect(ui->SendWordOrder,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendButton,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn1,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn2,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn3,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
}
第五步:刷新串口,及時更新可用的串口
// 刷新串口
void MainWindow::RefreshSerialPort(int index)
{
QStringList portNameList; // 存儲所有串口名
if(index != 0)
{
serial->setPortName(ui->PortBox->currentText()); //設置串口號
}
else
{
ui->PortBox->clear(); //關閉串口號
ui->PortBox->addItem("刷新"); //添加刷新
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口
{
portNameList.append(info.portName());
}
ui->PortBox->addItems(portNameList);
ui->PortBox->setCurrentIndex(1); // 當前串口號為COM1
serial->setPortName(ui->PortBox->currentText()); //設置串口號
}
}
第六步:發送數據和接收數據
// 接收數據,使用read () / readLine () / readAll ()
void MainWindow::DataReceived()
{
char BUF[512] = {0}; // 存儲轉換類型后的數據
QByteArray data = serial->readAll(); // 讀取數據
if(!data.isEmpty()) // 接收到數據
{
QString str = ui->DataReceived->toPlainText(); // 返回純文本
str += tr(data); // 數據是一行一行傳送的,要保存所有數據
ui->DataReceived->clear(); // 清空之前的數據
ui->DataReceived->append(str); // 將數據放入控件中
qDebug() << "str info: " << ui->DataReceived->toPlainText();
// 清除之前的數據,防止追加,因為每次獲取的數據不一樣
int index = str.indexOf("\\r\\n"); // 找到,返回索引值,找不到,返回-1
if(index != -1)
{
snprintf(BUF,500,"%s", str.left(index + 2).toUtf8().data()); // QString轉為char * 類型
qDebug() << "BUF info: " << BUF; // 數據類型轉換成功
str.remove(0,index + 2);
// 處理獲取到的數據,將其放入對應的控件中
// .....
}
}
}
// 發送數據,write ()
void MainWindow::DataSend()
{
serial->write(ui->DataSend->toPlainText().toLatin1()); // 串口發送數據
}
第七步:打開串口和關閉串口,當打開串口后,顯示綠燈;關閉串口后,顯示紅燈
// 串口開關
void MainWindow::on_OpenSerialButton_clicked()
{
if(serial->isOpen()) // 如果串口打開了,先給他關閉
{
serial->clear();
serial->close();
// 關閉狀態,按鈕顯示“打開串口”
ui->OpenSerialButton->setText("打開串口");
// 關閉狀態,允許用戶操作
ui->BaudBox->setDisabled(false);
ui->ParityBox->setDisabled(false);
ui->BitBox->setDisabled(false);
ui->StopBox->setDisabled(false);
ui->ControlBox->setDisabled(false);
// 禁止操作“發送字符操作”
ui->SendWordOrder->setDisabled(true);
ui->SendButton->setDisabled(true);
// 關閉狀態,顏色為綠色
ui->OpenSerialButton->setStyleSheet("color: green;");
// 關閉,顯示燈為紅色
LED(true);
// 清空數據
ui->DataReceived->clear();
ui->DataSend->clear();
}
else // 如果串口關閉了,先給他打開
{
//當前選擇的串口名字
serial->setPortName(ui->PortBox->currentText());
//用ReadWrite 的模式嘗試打開串口,無法收發數據時,發出警告
if(!serial->open(QIODevice::ReadWrite))
{
QMessageBox::warning(this,tr("提示"),tr("串口打開失敗!"),QMessageBox::Ok);
return;
}
// 打開狀態,按鈕顯示“關閉串口”
ui->OpenSerialButton->setText("關閉串口");
// 打開狀態,禁止用戶操作
ui->BaudBox->setDisabled(true);
ui->ParityBox->setDisabled(true);
ui->BitBox->setDisabled(true);
ui->StopBox->setDisabled(true);
ui->ControlBox->setDisabled(true);
// 允許操作“發送字符操作”
ui->SendWordOrder->setDisabled(false);
ui->SendButton->setDisabled(false);
// 打開狀態,顏色為紅色
ui->OpenSerialButton->setStyleSheet("color: red;");
// 打開,顯示燈為綠色
LED(false);
}
}
// 開關顯示燈
void MainWindow::LED(bool changeColor)
{
if(changeColor == false)
{
// 顯示綠色
ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
}
else
{
// 顯示紅色
ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
}
}
第八步:相關槽函數
// 控件中添加 指令“###”
void MainWindow::on_SendButton_clicked()
{
on_ClearButton_clicked();
ui->DataSend->append("###");
}
// 清空控件
void MainWindow::on_ClearButton_clicked()
{
ui->DataSend->setText("");
}
// 清空接收到的數據
void MainWindow::on_ClearShowButton_clicked()
{
ui->DataReceived->setText("");
}
// 點擊發送后,獲取串口信息并展示在接受控件中
void MainWindow::on_SendEditBtn1_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit1->text(); //獲取發送框內容
ui->DataSend->setText(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendEditBtn2_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit2->text(); //獲取發送框內容
// qDebug() << "Edit1 text: " << EditText;
ui->DataSend->append(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendEditBtn3_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit3->text(); //獲取發送框內容
// qDebug() << "Edit1 text: " << EditText;
ui->DataSend->append(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendWordOrder_clicked()
{
on_SendButton_clicked();
}
源碼:
工程文件.pro文件源碼:
QT += core gui
# 引入串口工程類型(第二步)
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked 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 it uses 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
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
頭文件源碼:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
// 引入串口通信的兩個頭文件(第一步)
#include // 提供訪問串口的功能
#include // 提供系統中存在的串口信息
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 串口功能
void SerialPortInit(); // 串口初始化(參數配置)
void RefreshSerialPort(int index); // 刷新串口
public slots:
// 串口槽函數
void DataReceived(); // 接收數據
private slots:
// 串口槽函數
void DataSend(); // 發送數據
void on_OpenSerialButton_clicked(); // 串口開關
void on_SendButton_clicked(); // 控件中添加 #
void on_ClearButton_clicked(); // 清空控件中的所有 #
void on_ClearShowButton_clicked(); // 清空接收到的數據
void LED(bool changeColor); // 開關顯示燈
// 點擊發送,接收數據
void on_SendEditBtn1_clicked();
void on_SendEditBtn2_clicked();
void on_SendEditBtn3_clicked();
void on_SendWordOrder_clicked();
private:
Ui::MainWindow *ui;
// 串口變量
QSerialPort *serial; // 定義全局的串口對象(第三步)
// 參數配置
QStringList baudList; //波特率
QStringList parityList; //校驗位
QStringList dataBitsList; //數據位
QStringList stopBitsList; //停止位
QStringList flowControlList; //控制流
};
#endif // MAINWINDOW_H
.cpp文件源碼:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
SerialPortInit();
}
// 串口初始化(參數配置)
void MainWindow::SerialPortInit()
{
serial = new QSerialPort; //申請內存,并設置父對象
// 獲取計算機中有效的端口號,然后將端口號的名稱給端口選擇控件
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
serial->setPort(info); // 在對象中設置串口
if(serial->open(QIODevice::ReadWrite)) // 以讀寫方式打開串口
{
ui->PortBox->addItem(info.portName()); // 添加計算機中的端口
serial->close(); // 關閉
} else
{
qDebug() << "串口打開失敗,請重試";
}
}
// 參數配置
// 波特率,波特率默認選擇57600 ,禁止用戶點擊
ui->BaudBox->addItem("57600");
serial->setBaudRate(QSerialPort::Baud57600);
ui->BaudBox->setDisabled(true);
// 校驗,校驗默認選擇無
ui->ParityBox->addItem("無");
serial->setParity(QSerialPort::NoParity);
// 數據位,數據位默認選擇8位
ui->BitBox->addItem("8");
serial->setDataBits(QSerialPort::Data8);
// 停止位,停止位默認選擇1位
ui->StopBox->addItem("1");
serial->setStopBits(QSerialPort::OneStop);
// 控制流,默認選擇無
ui->ControlBox->addItem("無");
serial->setFlowControl(QSerialPort::NoFlowControl);
// 刷新串口
RefreshSerialPort(0);
// 信號
connect(serial,&QSerialPort::readyRead,this,&MainWindow::DataReceived); // 接收數據
connect(ui->SendWordOrder,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendButton,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn1,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn2,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
connect(ui->SendEditBtn3,&QPushButton::clicked,this,&MainWindow::DataSend); // 發送數據
}
// 刷新串口
void MainWindow::RefreshSerialPort(int index)
{
QStringList portNameList; // 存儲所有串口名
if(index != 0)
{
serial->setPortName(ui->PortBox->currentText()); //設置串口號
}
else
{
ui->PortBox->clear(); //關閉串口號
ui->PortBox->addItem("刷新"); //添加刷新
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口
{
portNameList.append(info.portName());
}
ui->PortBox->addItems(portNameList);
ui->PortBox->setCurrentIndex(1); // 當前串口號為COM1
serial->setPortName(ui->PortBox->currentText()); //設置串口號
}
}
// 接收數據,使用read () / readLine () / readAll ()
void MainWindow::DataReceived()
{
char BUF[512] = {0}; // 存儲轉換類型后的數據
QByteArray data = serial->readAll(); // 讀取數據
if(!data.isEmpty()) // 接收到數據
{
QString str = ui->DataReceived->toPlainText(); // 返回純文本
str += tr(data); // 數據是一行一行傳送的,要保存所有數據
ui->DataReceived->clear(); // 清空之前的數據
ui->DataReceived->append(str); // 將數據放入控件中
qDebug() << "str info: " << ui->DataReceived->toPlainText();
// 清除之前的數據,防止追加,因為每次獲取的數據不一樣
int index = str.indexOf("\\r\\n"); // 找到,返回索引值,找不到,返回-1
if(index != -1)
{
snprintf(BUF,500,"%s", str.left(index + 2).toUtf8().data()); // QString轉為char * 類型
qDebug() << "BUF info: " << BUF;
str.remove(0,index + 2);
// 處理獲取到的數據,將其放入對應的控件中
// ....
}
}
}
// 發送數據,write ()
void MainWindow::DataSend()
{
serial->write(ui->DataSend->toPlainText().toLatin1()); // 串口發送數據
}
// 開關顯示燈
void MainWindow::LED(bool changeColor)
{
if(changeColor == false)
{
// 顯示綠色
ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 229, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
}
else
{
// 顯示紅色
ui->LED->setStyleSheet("background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(255, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));border-radius:12px;");
}
}
MainWindow::~MainWindow()
{
delete ui;
}
// 串口開關
void MainWindow::on_OpenSerialButton_clicked()
{
if(serial->isOpen()) // 如果串口打開了,先給他關閉
{
serial->clear();
serial->close();
// 關閉狀態,按鈕顯示“打開串口”
ui->OpenSerialButton->setText("打開串口");
// 關閉狀態,允許用戶操作
ui->BaudBox->setDisabled(false);
ui->ParityBox->setDisabled(false);
ui->BitBox->setDisabled(false);
ui->StopBox->setDisabled(false);
ui->ControlBox->setDisabled(false);
// 禁止操作“發送字符操作”
ui->SendWordOrder->setDisabled(true);
ui->SendButton->setDisabled(true);
// 關閉狀態,顏色為綠色
ui->OpenSerialButton->setStyleSheet("color: green;");
// 關閉,顯示燈為紅色
LED(true);
// 清空數據
ui->DataReceived->clear();
ui->DataSend->clear();
}
else // 如果串口關閉了,先給他打開
{
//當前選擇的串口名字
serial->setPortName(ui->PortBox->currentText());
//用ReadWrite 的模式嘗試打開串口,無法收發數據時,發出警告
if(!serial->open(QIODevice::ReadWrite))
{
QMessageBox::warning(this,tr("提示"),tr("串口打開失敗!"),QMessageBox::Ok);
return;
}
// 打開狀態,按鈕顯示“關閉串口”
ui->OpenSerialButton->setText("關閉串口");
// 打開狀態,禁止用戶操作
ui->BaudBox->setDisabled(true);
ui->ParityBox->setDisabled(true);
ui->BitBox->setDisabled(true);
ui->StopBox->setDisabled(true);
ui->ControlBox->setDisabled(true);
// 允許操作“發送字符操作”
ui->SendWordOrder->setDisabled(false);
ui->SendButton->setDisabled(false);
// 打開狀態,顏色為紅色
ui->OpenSerialButton->setStyleSheet("color: red;");
// 打開,顯示燈為綠色
LED(false);
}
}
// 控件中添加 #
void MainWindow::on_SendButton_clicked()
{
on_ClearButton_clicked();
ui->DataSend->append("###");
}
// 清空控件
void MainWindow::on_ClearButton_clicked()
{
ui->DataSend->setText("");
}
// 清空接收到的數據
void MainWindow::on_ClearShowButton_clicked()
{
ui->DataReceived->setText("");
}
// 點擊發送后,獲取串口信息并展示在接受控件中
void MainWindow::on_SendEditBtn1_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit1->text(); //獲取發送框內容
ui->DataSend->setText(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendEditBtn2_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit2->text(); //獲取發送框內容
// qDebug() << "Edit1 text: " << EditText;
ui->DataSend->append(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendEditBtn3_clicked()
{
on_ClearButton_clicked();
QString EditText = ui->Edit3->text(); //獲取發送框內容
// qDebug() << "Edit1 text: " << EditText;
ui->DataSend->append(EditText); //將文本內容放在發送欄中
}
void MainWindow::on_SendWordOrder_clicked()
{
on_SendButton_clicked();
}
運行后效果:
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
顯示器
+關注
關注
22文章
5072瀏覽量
141813 -
串口
+關注
關注
15文章
1588瀏覽量
79917 -
串口通信
+關注
關注
34文章
1639瀏覽量
56806 -
波特率
+關注
關注
2文章
313瀏覽量
34935
發布評論請先 登錄
相關推薦
熱點推薦
實現基于Qt的上位機與下位機進行串口通信
:Qt5.96Mingw32-bit keil3項目目標1、實現下位機基于STC單片機控制LED燈模塊、獨立鍵盤模塊.2、實現基于Qt的上位機與下位機進行
發表于 12-08 07:26
QT 串口通信,操作程控電源 Agilent 66312A
背景:用QT來寫個串口通信小工具,操作程控電源Agilent 66312A ,能夠設置電壓,獲取電流步驟:1、Agilent 66312A RS-232配置按圖中步驟,確保程控電壓調制RS-232
發表于 01-12 12:44
?17次下載

基于Qt實現的串口示波器
摘要:逛github時看到這個QT的串口示波器,完全開源,支持串口、TCP、波形顯示、通信協議。感覺很不錯,跟以前分享的那個vofa+有點像。感興趣的可以下載下來學習學習。
QT與三菱PLC串口通信
最近兩天在學習QT與三菱PLC串口通信,特此記錄下來。 通信格式 我這里使用RS-232C連接的,根據FX編程口協議! 設置參數,以讀寫的方式打開串
發表于 04-17 16:08
?0次下載

QT篇QT上位機串口編程
QT 篇 QT上位機串口編程 最近因為項目需要,需要用到上位機,通過串口與上位機進行通訊,來上傳和下發一些數據以及控制指令,所以用QT寫了一
發表于 05-08 10:02
?25次下載

Qt5實現上位機與串口通信
Qt助手內搜索:Qt Serial Port為串口的相關函數? 1.添加串口頭文件: # include //使用串口功能# inc
發表于 05-10 10:46
?0次下載

評論