当前位置:网站首页>C2-qt serial port debugging assistant 2021.10.21
C2-qt serial port debugging assistant 2021.10.21
2022-06-22 02:44:00 【Morning and evening rain】
Qt Realize serial port debugging assistant
1. The goal is
Realize serial port debugging assistant , The interface style is concise , Configurable key communication parameters include , Baud rate 、 Stop bit 、 Data bits 、 Check bit ; We can use 16 Binary transmit data , With 16 Base or ascii Code receiving data , Support to save the received data to local txt.
notes : see FPGA Lower computer serial port code implementation , Please check out FPGA Serial port communication
download FPGA Serial communication engineering documents and codes , Please check out FPGA Serial port communication vivado engineering
2. step
2.1.pro Add , Serial port module .
The module Qt5 Support ,Qt4 I won't support it ;
QT += serialport
2.2 Serial port related classes
#include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort/QSerialPort>
QSerialPortInfo This class will get the serial port information , as follows :
qDebug()<<"serialPortName:"<<info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
qDebug() << "Serial Number: " << info.serialNumber();
qDebug() << "System Location: " << info.systemLocation();
QSerialPort There are many ways , As basic as open、close、read、write Method , And error handling 、 Set serial port parameters and other methods , Will coordinate the work , Jointly complete the operation of serial port sending and receiving .
2.3 Interface prototype construction
Some interface layout details , The typesetting principle is fully reflected in the following interface prototype with infinite fidelity , This setup does not require manual code .
2.4 Interface logic
(1) call Init() function , The initialization function will complete the following functions
First, check the current online serial port device , And write it into the drop-down box ;
Initialize baud rate selection drop-down box , And check bits 、 Stop bit 、 Data bits ;
Set the default to 16 Base display ;
Clear receive buffer ( Black areas ).
(2) Make button function connection
” Scan the serial port “ Button to rescan the current serial port device , And update its status to the corresponding drop-down box ;
“ Open the serial port ” Button to issue serial port configuration and open serial port , Add open failure mode to prompt the user , Successfully added and opened, the button changes to “ Turn off the serial port ”;
" Turn off the serial port " The button will clear Serial port and close the serial port ;
“ Clear receive ” take textEdit clear fall ;
“ Save window ” Save the contents of the current receiving box to... Under the project directory txt, And clear the current receiving frame ;
“ send out ” Data processing operation will be performed and sent to the open serial port , Of course, there will be a prompt of serial port failure ;
“ Clear send ” The current send box will be cleared ;
(3) Adjust interface logic details
“ A serial port choice ”QFrame Fixed size , Does not change with the size of the interface ;
“ A serial port choice ” The overall vertical layout after the horizontal layout of the middle horizontal elements ;
“ Receiving frame ” Read only mode ;
Set up “ Receiving frame ” Style sheets , Black background , Green font ;
“ Send box ” Show me by default logo;
2.5 The underlying logic
(1) Get the current configuration function , The return value is the enumeration type , convenient “ Open the serial port ” Called when the , Take the current configuration of the check bit as an example , as follows :
enum QSerialPort::Parity MainWindow::getParity()
{
QString currentParityBit = ui->checkBit_Sel->currentText();
if (currentParityBit == "None")
return QSerialPort::NoParity;
else if (currentParityBit == "Odd")// Odd number
return QSerialPort::OddParity;
else if (currentParityBit == "Even")// Even check
return QSerialPort::EvenParity;
else
return QSerialPort::UnknownParity;
}
(2) receive data , The serial port data buffer will send a signal when receiving data &QSerialPort::readyRead, Therefore, the user only needs to write the slot function and link it .
notice:
(2.1) For example, the other party sends 0x11、0x22、0x33、0x44、0x55, The data of , It may trigger many times ReadSerialData() call , This is not the end of the collection 5 Data , Will trigger once , But the data read away , I won't read it again next time , This can be assured ;
(2.2) Here we need to judge what is read QByteArray Of buffer Is it empty , I have encountered during debugging , Empty data , It also triggers an entry into the slot function ;
(2.3) receive ( send out ) The data type is QByteArray The type of , The receiving side needs to perform data type conversion to facilitate display processing
str.append(QString::number((ary[i]&0xff),16));//QByteArray-->QString
(2.4) Receive operation read、readAll, And send operation write Are non blocking operations , That is, function execution , Whether or not all data is received ( send out ), Functions will immediately return , The program will continue .
(2.5) Support 16 The display of decimal system 、Ascii Display of codes ( Two types of data processing )
(3) send data
The default in accordance with the 16 Send data in hexadecimal mode , Therefore, only 16 Hexadecimal related character input , Other characters will not be allowed .
3. Code
3.1.cpp File code
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QByteArray>
#include <QTextDecoder>
#include <QTextCodec>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//QAbstractNativeEventFilter QT System event filter , For example, the serial port plug-in can identify
// That is, real-time detection of equipment status by means of interruption
Init();// Initialization function , effect : Scan the online serial port ; Fill baud rate 、 Check bit 、 Data bits 、 Stop bit widget
// Rescan the online serial port ( Displays the current device status )
connect(ui->scanBtn,&QPushButton::clicked,[=](){
ui->comboBox->clear();
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
ui->comboBox->addItem(info.portName());
}
});
// Turn on the serial button
connect(ui->openBtn,&QPushButton::clicked,[=](){
if(ui->openBtn->text()==" Open the serial port ")
{
// qDebug()<<getBaud()<<getParity()<<getdataBits()<<getstopBits();
mySerialPort->setPortName(ui->comboBox->currentText());
mySerialPort->setBaudRate(getBaud());
mySerialPort->setParity(getParity());
mySerialPort->setDataBits(getdataBits());
mySerialPort->setStopBits(getstopBits());
// mySerialPort->setFlowControl(QSerialPort::NoFlowControl); // TODO: FlowControl
// mySerialPort->setReadBufferSize(0); // The buffer is infinite
if(!(mySerialPort->open(QSerialPort::ReadWrite)))
{
// The standard dialog box prompts that opening the serial port failed
QMessageBox::warning(this," Warning "," Failed to open serial port ");
}
else
{
ui->openBtn->setText(" Turn off the serial port ");
}
}
else
{
mySerialPort->clear();
mySerialPort->close();
ui->openBtn->setText(" Open the serial port ");
}
});
// Save button
connect(ui->saveBtn,&QPushButton::clicked,[=](){
QFile file("UART_Rec.txt");
file.open(QIODevice::Append);
// Use QTextStream write file
QTextStream tsm(&file);
tsm<<ui->reci_Edit->toPlainText();
ui->reci_Edit->clear();
file.close();
});
// Clear the receive button
connect(ui->clearRecBtn,&QPushButton::clicked,[=](){
ui->reci_Edit->clear();
});
// Clear the send button
connect(ui->clearXferBtn,&QPushButton::clicked,[=](){
ui->xferEdit->clear();
});
// Send button
connect(ui->xferBtn, &QPushButton::clicked, this, [=](){
if(!mySerialPort->isOpen())
{
QMessageBox::information(this," Tips "," Please open the serial port first ");
}
else
{
// // Get the send box character
QString str = ui->xferEdit->document()->toPlainText();
if (str.isEmpty())
{
QMessageBox::information(this," Tips "," Please enter the sending content first ");
}
// Default 16 Base send , Filter useless characters Include 0x
else
{
char ch;
bool flag = false;
uint32_t i, len;
// Get rid of useless symbols
str = str.replace(' ',"");
str = str.replace(',',"");
str = str.replace('\r',"");
str = str.replace('\n',"");
str = str.replace('\t',"");
str = str.replace("0x","");
str = str.replace("0X","");
str = str.replace('\\',"");
str = str.replace(':',"");
str = str.replace('?',"");
str = str.replace(';',"");
// Judge the validity of data
for(i = 0, len = str.length(); i < len; i++)
{
ch = str.at(i).toLatin1();
if (ch >= '0' && ch <= '9')
{
flag = false;
}
else if (ch >= 'a' && ch <= 'f')
{
flag = false;
}
else if (ch >= 'A' && ch <= 'F')
{
flag = false;
}
else
{
flag = true;
}
}
if(flag)
{
QMessageBox::warning(this," Warning "," The input contains illegal 16 Hexadecimal characters ");
}
else
{
//QString turn QByteArray
QByteArray xferAry = str.toUtf8();
mySerialPort->write(xferAry);
}
}
}
});
// receive Buffer
connect(mySerialPort,&QSerialPort::readyRead,[=](){
if(ui->hex_Rtn->isChecked())
{
// With 16 Base display
QByteArray ary = mySerialPort->readAll();
qDebug()<<ary;
QString str;
str.clear();
for (int i = 0;i<ary.size()-2 ;i++ ) {
str.append(QString::number((ary[i]&0xff),16));// take 16 Hexadecimal output as is
// str.append(" ");
}
ui->reci_Edit->append(str);
// ui->reci_Edit->append("\n");
}
else
{
// With Ascii Code display Ascii Code means 16 The character corresponding to base , Namely ascii One of the rules 16 Mapping between base and character
ui->reci_Edit->append(mySerialPort->readAll());
ui->reci_Edit->append("\n");
}
});
}
MainWindow::~MainWindow()
{
if(mySerialPort->isOpen())
{
mySerialPort->clear();
mySerialPort->close();
}
delete mySerialPort;
delete ui;
}
enum QSerialPort::Parity MainWindow::getParity()
{
QString currentParityBit = ui->checkBit_Sel->currentText();
if (currentParityBit == "None")
return QSerialPort::NoParity;
else if (currentParityBit == "Odd")// Odd number
return QSerialPort::OddParity;
else if (currentParityBit == "Even")// Even check
return QSerialPort::EvenParity;
else
return QSerialPort::UnknownParity;
}
enum QSerialPort::BaudRate MainWindow::getBaud()
{
bool ok;
enum QSerialPort::BaudRate ret;
switch (ui->baud_Sel->currentText().toLong(&ok, 10))
{
case 1200:
ret = QSerialPort::Baud1200;
break;
case 2400:
ret = QSerialPort::Baud2400;
break;
case 4800:
ret = QSerialPort::Baud4800;
break;
case 9600:
ret = QSerialPort::Baud9600;
break;
case 19200:
ret = QSerialPort::Baud19200;
break;
case 38400:
ret = QSerialPort::Baud38400;
break;
case 57600:
ret = QSerialPort::Baud57600;
break;
case 115200:
ret = QSerialPort::Baud115200;
break;
default:
ret = QSerialPort::UnknownBaud;
break;
}
return ret;
}
enum QSerialPort::StopBits MainWindow::getstopBits()
{
QString currentStopBits = ui->stopBit_Sel->currentText();
if (currentStopBits == "1")
return QSerialPort::OneStop;
else if (currentStopBits == "1.5")
return QSerialPort::OneAndHalfStop;
else if (currentStopBits == "2")
return QSerialPort::TwoStop;
else
return QSerialPort::UnknownStopBits;
}
enum QSerialPort::DataBits MainWindow::getdataBits()
{
QString currentDataBits = ui->dataBit_Sel->currentText();
if(currentDataBits == "5")
return QSerialPort::Data5;
else if (currentDataBits == "6")
return QSerialPort::Data6;
else if (currentDataBits == "7")
return QSerialPort::Data7;
else if (currentDataBits == "8")
return QSerialPort::Data8;
else
return QSerialPort::UnknownDataBits;
}
void MainWindow::Init()
{
// First scan the current serial port , initialization COM Port selection component
QStringList myPortName;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
myPortName << info.portName();
qDebug()<<"serialPortName:"<<info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
qDebug() << "Serial Number: " << info.serialNumber();
qDebug() << "System Location: " << info.systemLocation();
}
myPortName.sort();
ui->comboBox->addItems(myPortName);
// Initialize the baud rate component
QStringList myBaud;
myBaud.clear();
myBaud<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"57600"<<"115200";
ui->baud_Sel->addItems(myBaud);
ui->baud_Sel->setCurrentText("9600");
// Initialize stop bit
QStringList mystopBits;
mystopBits.clear();
mystopBits<<"1"<<"1.5"<<"2";
ui->stopBit_Sel->addItems(mystopBits);
ui->stopBit_Sel->setCurrentText("1");
// Initialize check bit
QStringList mycheckBits;
mycheckBits.clear();
mycheckBits<<"None"<<"Even"<<"Odd";
ui->checkBit_Sel->addItems(mycheckBits);
ui->checkBit_Sel->setCurrentText("None");
// Initialize data bits
QStringList mydataBits;
mydataBits.clear();
mydataBits<<"5"<<"6"<<"7"<<"8";
ui->dataBit_Sel->addItems(mydataBits);
ui->dataBit_Sel->setCurrentText("8");
ui->hex_Rtn->setChecked(true);// The default setting is 16 Base display
ui->reci_Edit->clear();
}
3.2.h Code
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort/QSerialPort>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
enum QSerialPort::Parity getParity();
enum QSerialPort::BaudRate getBaud();
enum QSerialPort::StopBits getstopBits();
enum QSerialPort::DataBits getdataBits();
void Init();
// Create a serial port object
QSerialPort *mySerialPort = new QSerialPort();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
4. effect
Use virtual serial port software VSPD Virtual serial port , Use mature software XCOM V2.0( Punctual atomic serial port debugging assistant ) Communicate with your own software , Can be seen clearly , Software receiving and sending are normal .VSPD For software acquisition and installation, please see Tool class – Virtual serial tools

5. reflection
Two ideas ,1.USB It belongs to hot plug device , The system can dynamically detect the insertion and disconnection of equipment , So how to make your software dynamically view the connection status of serial port devices ? actually ,Qt Provides “ interrupt ” Interface , It can be upgraded ;
2. Now it only supports 16 Base send , Support 16 Base number 、ascii Code reception , So can we consider using serial port to transmit Chinese characters ? actually ,Qt Support multiple character sets , Try it .
边栏推荐
- Latest release: neo4j figure data science GDS 2.0 and aurads GA
- DAST black box vulnerability scanner part 4: scanning performance
- With the acceleration of industry wide digital transformation, what kind of storage will be more popular?
- 【5. 高精度减法】
- 国产品牌OPPO官方最新出品!这份PPT报告!真刷新我对它认知了
- Markdown is proficient in Elementary Grammar and is compatible with marktext
- Rational Rose installation tutorial
- 【一起上水硕系列】Day Two
- Try catch of Bash
- Transformation numérique des RH avec okr
猜你喜欢
![[6. high precision multiplication]](/img/83/1659503e62839c395ca7849596d6fc.png)
[6. high precision multiplication]

Technical exploration: 360 digital subjects won the first place in the world in ICDAR OCR competition

Wechat applet film and television review and exchange platform system graduation design completion (7) Interim inspection report

C ++ Primer 第2章 变量和基本类型 总结

使用 Neo4j 沙箱学习 Neo4j 图数据科学 GDS

从数据库的分类说起,一文了解图数据库

银联支付 返回商户 Nignx post请求405

Graphacademy course explanation: Fundamentals of neo4j graph data science

EMC Radiation Emission rectification - principle Case Analysis

Wechat applet film and television review and exchange platform system graduation design (1) development outline
随机推荐
Matlab learning notes (5) import and export of MATLAB data
PMP reference related agile knowledge
The latest official product of domestic brand oppo! This ppt report! It really refreshes my understanding of it
A short video costs hundreds of thousands of yuan, and the virtual digital man makes a circle with "strength"
最新發布:Neo4j 圖數據科學 GDS 2.0 和 AuraDS GA
自动化工具-监测文件的变化
Wechat applet film and television review and exchange platform system graduation design completion (7) Interim inspection report
C++ primer Chapter 2 summary of variables and basic types
【7. 高精度除法】
Create RT_ Thread thread
Live broadcast on June 22 | zhanzhihui, South China Institute of Technology: evolutionary computing for expensive optimization
Unicode decodeerror appears: 'ASCII' codec can't decode byte 0xe9 in position 0: ordinal not in range solution
Architecture and practice of vivo container cluster monitoring system
Neo4j 技能树正式发布,助你轻松掌握Neo4j图数据库
Graphacademy course explanation: Fundamentals of neo4j graph data science
Wechat applet film and television comment exchange platform system graduation design (2) applet function
Huayang smart rushes to Shenzhen Stock Exchange: it plans to raise 400million Fosun Weiying as a shareholder
【1. 快速排序】
In the era of industrial Internet, there is no real center
On Monday, I asked the meaning of the | -leaf attribute?