今天我们首先来完善数据接收功能, 同时完成数据发送功能
一. 完善数据接收功能
主要有以下几点需要完善:
- 需要接收中文
- 打开串口的pushbotton,点击打开后需要改为关闭串口功能
1. 完善接收中文功能
这一块我在帮助手册上是找不到解决办法,只能在网上看有没有解决办法了, 参考了网上这位博主的https://blog.csdn.net/ouening/article/details/89469468,接收函数修改为
/*显示串口数据函数*/
void MainWindow::displayData()
{
QByteArray rx_data;
rx_data = this->serialPortUsing.readAll();
QString str = QString::fromLocal8Bit(rx_data);
qDebug() << str;
rx_data.clear();
}
就可以愉快的显示中文了
2. 完善打开串口和关闭串口功能
做这个功能的思路是先定义一个bool类型的打开与否标志位,点击了打开串口就把这个标志位翻转,再次点击时 在槽函数里面判断这个标志位,做相应的打开或者关闭操作。
mainwindow.cpp代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QComboBox>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*显示波特率*/
this->BaudList << "9600" << "19200" <<"115200";
ui->baudComboBox->addItems(this->BaudList);
/*刷新串口*/
this->refreshPort();
/* 点击刷新功能显示*/
connect(ui->refreshPortBtn, &QPushButton::clicked, this, &MainWindow::refreshPort);
/* 点击打开串口*/
connect(ui->openSerialBtn, &QPushButton::clicked, this, &MainWindow::openPort);
/* 显示串口数据 */
connect(&this->serialPortUsing, &QSerialPort::readyRead , this, &MainWindow::displayData);
}
/*刷新串口处理函数*/
void MainWindow::refreshPort()
{
qDebug() << "刷新串口";
/*清除comboxBox的内容,防止显示重复的串口*/
ui->displayPortComboBox->clear();
/* 读取可以使用的串口*/
this->avaiPortsList = QSerialPortInfo::availablePorts();
/* 提取串口个数*/
int avaiPortNum = avaiPortsList.length();
/*逐个显示*/
for(int i = 0; i < avaiPortNum; i++)
{
ui->displayPortComboBox->addItem(this->avaiPortsList[i].portName());
}
}
/*打开串口处理函数*/
void MainWindow::openPort()
{
if(!this->isOpenSerial)
{
/*读取当前的波特率和端口号*/
qDebug() << "打开串口号:"<< ui->displayPortComboBox->currentText()<<"波特率:"<<ui->baudComboBox->currentText().toInt();
/* 获取串口序号和波特率序号 */
/*设置当前串口号*/
int displayPortComboBoxCurrIndex = ui->displayPortComboBox->currentIndex();
this->serialPortInfoUsing = this->avaiPortsList[displayPortComboBoxCurrIndex];
this->serialPortUsing.setPort(this->serialPortInfoUsing);
/*设置波特率*/
this->serialPortUsing.setBaudRate(ui->baudComboBox->currentText().toInt());
/*设置数据位:8位*/
this->serialPortUsing.setDataBits(QSerialPort::Data8);
/*设置停止位: 1位*/
this->serialPortUsing.setStopBits(QSerialPort::OneStop);
/*设置校验位: 无校验*/
this->serialPortUsing.setParity(QSerialPort::NoParity);
/*设置流控制: 无硬件流控制*/
this->serialPortUsing.setFlowControl(QSerialPort::NoFlowControl);
/*打开串口*/
if(this->serialPortUsing.open(QIODevice::ReadWrite))
{
qDebug() << "打开串口成功!";
this->isOpenSerial = true;
ui->openSerialBtn->setText("关闭串口");
}
else
{
qDebug() << "打开串口失败!";
}
}
else
{
qDebug() << "关闭串口";
this->isOpenSerial = false;
this->serialPortUsing.close();
ui->openSerialBtn->setText("打开串口");
}
}
/*显示串口数据函数*/
void MainWindow::displayData()
{
QByteArray rx_data;
rx_data = this->serialPortUsing.readAll();
QString str = QString::fromLocal8Bit(rx_data);
qDebug() << str;
rx_data.clear();
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
/* 定义可用端口列表变量*/
QList<QSerialPortInfo> avaiPortsList;
/* 定义波特率列表*/
QStringList BaudList;
/* 定义正在使用的串口对象*/
QSerialPort serialPortUsing;
/* 定义正在使用的串口信息对象*/
QSerialPortInfo serialPortInfoUsing;
/* 定义是否打开串口标志位 */
bool isOpenSerial = false;
/*刷新串口信号*/
void refreshPort(void);
/*打开串口信号*/
void openPort(void);
/*显示串口数据*/
void displayData(void);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
实验现象
二. 完善数据发送功能
整体思路:首先页面上增加一个按键, 点击按键时发送一个固定的字符串到下位机。
1. 页面布局
2. 代码实现
发送数据的方法是write函数
- 首先是绑定信号和槽函数
/* 发送串口数据 */
connect(ui->sendDataBtn, &QPushButton::clicked, this, &MainWindow::sendData);
- 然后再写发送测试函数
/*发送串口数据函数*/
void MainWindow::sendData()
{
this->serialPortUsing.write("hello world!\r\n");
}
- 写下位机程序
我这里直接把下位机的TX和RX短接了,相当于上位机发送什么,下位机就会返回什么,这样就可以看见返回的数据了。 - 实验效果
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QComboBox>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*显示波特率*/
this->BaudList << "9600" << "19200" <<"115200";
ui->baudComboBox->addItems(this->BaudList);
/*刷新串口*/
this->refreshPort();
/* 点击刷新功能显示*/
connect(ui->refreshPortBtn, &QPushButton::clicked, this, &MainWindow::refreshPort);
/* 点击打开串口*/
connect(ui->openSerialBtn, &QPushButton::clicked, this, &MainWindow::openPort);
/* 显示串口数据 */
connect(&this->serialPortUsing, &QSerialPort::readyRead , this, &MainWindow::displayData);
/* 发送串口数据 */
connect(ui->sendDataBtn, &QPushButton::clicked, this, &MainWindow::sendData);
}
/*刷新串口处理函数*/
void MainWindow::refreshPort()
{
qDebug() << "刷新串口";
/*清除comboxBox的内容,防止显示重复的串口*/
ui->displayPortComboBox->clear();
/* 读取可以使用的串口*/
this->avaiPortsList = QSerialPortInfo::availablePorts();
/* 提取串口个数*/
int avaiPortNum = avaiPortsList.length();
/*逐个显示*/
for(int i = 0; i < avaiPortNum; i++)
{
ui->displayPortComboBox->addItem(this->avaiPortsList[i].portName());
}
}
/*打开串口处理函数*/
void MainWindow::openPort()
{
if(!this->isOpenSerial)
{
/*读取当前的波特率和端口号*/
qDebug() << "打开串口号:"<< ui->displayPortComboBox->currentText()<<"波特率:"<<ui->baudComboBox->currentText().toInt();
/* 获取串口序号和波特率序号 */
/*设置当前串口号*/
int displayPortComboBoxCurrIndex = ui->displayPortComboBox->currentIndex();
this->serialPortInfoUsing = this->avaiPortsList[displayPortComboBoxCurrIndex];
this->serialPortUsing.setPort(this->serialPortInfoUsing);
/*设置波特率*/
this->serialPortUsing.setBaudRate(ui->baudComboBox->currentText().toInt());
/*设置数据位:8位*/
this->serialPortUsing.setDataBits(QSerialPort::Data8);
/*设置停止位: 1位*/
this->serialPortUsing.setStopBits(QSerialPort::OneStop);
/*设置校验位: 无校验*/
this->serialPortUsing.setParity(QSerialPort::NoParity);
/*设置流控制: 无硬件流控制*/
this->serialPortUsing.setFlowControl(QSerialPort::NoFlowControl);
/*打开串口*/
if(this->serialPortUsing.open(QIODevice::ReadWrite))
{
qDebug() << "打开串口成功!";
this->isOpenSerial = true;
ui->openSerialBtn->setText("关闭串口");
}
else
{
qDebug() << "打开串口失败!";
}
}
else
{
qDebug() << "关闭串口";
this->isOpenSerial = false;
this->serialPortUsing.close();
ui->openSerialBtn->setText("打开串口");
}
}
/*显示串口数据函数*/
void MainWindow::displayData()
{
QByteArray rx_data;
rx_data = this->serialPortUsing.readAll();
QString str = QString::fromLocal8Bit(rx_data);
qDebug() << str;
rx_data.clear();
}
/*发送串口数据函数*/
void MainWindow::sendData()
{
this->serialPortUsing.write("hello world!\r\n");
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
/* 定义可用端口列表变量*/
QList<QSerialPortInfo> avaiPortsList;
/* 定义波特率列表*/
QStringList BaudList;
/* 定义正在使用的串口对象*/
QSerialPort serialPortUsing;
/* 定义正在使用的串口信息对象*/
QSerialPortInfo serialPortInfoUsing;
/* 定义是否打开串口标志位 */
bool isOpenSerial = false;
/*刷新串口信号*/
void refreshPort(void);
/*打开串口信号*/
void openPort(void);
/*显示串口数据*/
void displayData(void);
/*发送串口数据*/
void sendData(void);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H