QT实现串口调试器

时间:2022-12-06 19:02:54
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QSerialPort"
#include "QSerialPortInfo"
#include "QMessageBox"
#include "QDateTime"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置左右比例为2:8
// ui->splitter_left_right->setStretchFactor(0,2);
// ui->splitter_left_right->setStretchFactor(1,8);

//设置上下比例为7:3
// ui->splitter_top_bot->setStretchFactor(0, 7);
// ui->splitter_top_bot->setStretchFactor(1, 3);

scanSerialPort();
baudInit();
databitInit();
stopbitInit();
parityInit();

serialPort = new QSerialPort(this);
ui->checkBox_autoline->setChecked(true);
ui->checkBox_timestamp_send->setChecked(true);
portOpened = false;
ui->pushButton_send->setEnabled(false);
connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialPortReadyRead()));
}

int MainWindow::sendBytes = 0;
int MainWindow::receBytes = 0;

MainWindow::~MainWindow()
{
delete ui;
}


//获取可用的串口
void MainWindow::scanSerialPort()
{
ui->comboBox_port->clear();
//for循环,检测系统可用的串口号
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
ui->comboBox_port->addItem(info.portName());
}
}

//设置波特率
void MainWindow::baudInit()
{
QList <QString> list;
list<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"57600"<<"115200";

for (int i = 0; i < 8; i++) {
ui->comboBox_baud->addItem(list[i]);
}
ui->comboBox_baud->setCurrentIndex(3);
}

//设置数据位
void MainWindow::databitInit()
{
QList <QString> list;
list<<"5"<<"6"<<"7"<<"8";

for (int i = 0; i < 4; i++) {
ui->comboBox_databit->addItem(list[i]);
}
ui->comboBox_databit->setCurrentIndex(3);
}

//设置停止位
void MainWindow::stopbitInit()
{
QList <QString> list;
list<<"1"<<"2";

for (int i = 0; i < 2; i++) {
ui->comboBox_stopbit->addItem(list[i]);
}
ui->comboBox_stopbit->setCurrentIndex(0);
}

//设置校验位
void MainWindow::parityInit()
{
QList <QString> list;
list<<"None"<<"Even"<<"Odd"<<"Space"<<"Mark";

for (int i = 0; i < 5; i++) {
ui->comboBox_parity->addItem(list[i]);
}
ui->comboBox_parity->setCurrentIndex(0);
}

//设置串口参数、打开串口
void MainWindow::on_pushButton_open_clicked()
{
//在串口未打开时,设置数据位、波特率、停止位、校验位
if (portOpened == false) {
serialPort->setPortName(ui->comboBox_port->currentText());
//设置串口名
serialPort->setBaudRate(ui->comboBox_baud->currentText().toInt());
//设置波特率
switch ( ui->comboBox_baud->currentIndex()) {
case 0:
serialPort->setBaudRate(QSerialPort::Baud1200);
break;
case 1:
serialPort->setBaudRate(QSerialPort::Baud2400);
break;
case 2:
serialPort->setBaudRate(QSerialPort::Baud4800);
break;
case 3:
serialPort->setBaudRate(QSerialPort::Baud9600);
break;
case 4:
serialPort->setBaudRate(QSerialPort::Baud19200);
break;
case 5:
serialPort->setBaudRate(QSerialPort::Baud38400);
break;
case 6:
serialPort->setBaudRate(QSerialPort::Baud57600);
break;
case 7:
serialPort->setBaudRate(QSerialPort::Baud115200);
break;
default:
break;
}
//设置数据位
switch (ui->comboBox_databit->currentText().toInt()) {
case 5:
serialPort->setDataBits(QSerialPort::Data5);
break;
case 6:
serialPort->setDataBits(QSerialPort::Data6);
break;
case 7:
serialPort->setDataBits(QSerialPort::Data7);
break;
case 8:
serialPort->setDataBits(QSerialPort::Data8);
break;
default:
break;
}

//设置停止位
switch (ui->comboBox_stopbit->currentText().toInt()) {
case 1:
serialPort->setStopBits(QSerialPort::OneStop);
break;
case 2:
serialPort->setStopBits(QSerialPort::TwoStop);
break;
default:
break;
}

switch (ui->comboBox_parity->currentIndex()) {
case 0:
serialPort->setParity(QSerialPort::NoParity);
break;
case 1:
serialPort->setParity(QSerialPort::EvenParity);
break;
case 2:
serialPort->setParity(QSerialPort::OddParity);
break;
case 3:
serialPort->setParity(QSerialPort::SpaceParity);
break;
case 4:
serialPort->setParity(QSerialPort::MarkParity);
break;
default:
break;
}
if (!serialPort->open(QIODevice::ReadWrite)) {
QMessageBox::warning(NULL, "错误", "串口打开失败");
} else {
portOpened = true;
ui->comboBox_baud->setEnabled(false);
ui->comboBox_databit->setEnabled(false);
ui->comboBox_parity->setEnabled(false);
ui->comboBox_port->setEnabled(false);
ui->comboBox_stopbit->setEnabled(false);
ui->pushButton_open->setText("关闭");
ui->pushButton_send->setEnabled(true);
}
} else {
// close serial port
serialPort->close();
portOpened = false;
ui->comboBox_baud->setEnabled(true);
ui->comboBox_databit->setEnabled(true);
ui->comboBox_parity->setEnabled(true);
ui->comboBox_port->setEnabled(true);
ui->comboBox_stopbit->setEnabled(true);
ui->pushButton_open->setText("打开");
ui->pushButton_send->setEnabled(false);
}
}

//清空接收区数据
void MainWindow::on_pushButton_clean_recv_clicked()
{
ui->textBrowser->clear();
}

//清空发送区数据
void MainWindow::on_pushButton_clean_send_clicked()
{
ui->textEdit->clear();
}

//发送
void MainWindow::on_pushButton_send_clicked()
{
//原先的写法
// QByteArray data = ui->textEdit->toPlainText().toUtf8();
// serialPort->write(data);
// serialPort->waitForBytesWritten(data.size());
// //按照字节去写
//修改后的写法
QString str = ui->textEdit->toPlainText().toUtf8();
if (!str.isEmpty())
{
auto isHexSend = ui->checkBox_hex_send->isChecked();
int len = str.length();

if (len%2 == 1)
{
str = str.insert(len-1,'0');
}
QByteArray sendata;
if (isHexSend)
{
StringToHex(str, sendata);
serialPort->write(sendata);
//写数据
//如果写的数据长度大小小于 0
if (serialPort->write(sendata) < 0)
{
QMessageBox::warning(this, tr("error1"), serialPort->errorString());
}
}
else
{
if (serialPort->write(ui->textEdit->toPlainText().toLocal8Bit())<0)
{
QMessageBox::critical(this, tr("error2"),serialPort->errorString());
}
}
}


}

void MainWindow::StringToHex(QString str, QByteArray &senddata)
{
int hexdata;
int lowhexdata;
int hexdatalen = 0;
int len = str.length();
senddata.resize(len/2);
char lstr;
char hstr;
for (int i = 0; i<len; )
{
hstr = str[i].toLatin1();
if (hstr == ' ')
{
i++;
continue;
}
i++;
if (i>=len)
break;
lstr = str[i].toLatin1();
hexdata = convertHexChart(hstr);
lowhexdata = convertHexChart(lstr);
if ((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata*16 + lowhexdata;
i++;
senddata[hexdata] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
}

char MainWindow::convertHexChart(char ch)
{
if ((ch >'0') && (ch < '9'))
return ch-0x30;
else if ((ch >='A') && ( ch <= 'F'))
return ch - 'A' +10;
else if ((ch >= 'a') && (ch <= 'f'))
return ch-'a' +10;
else
return ch-ch;
}


//准备去读
void MainWindow::serialPortReadyRead()
{
QByteArray data;
if (serialPort)
{
if (!data.isEmpty())
{
if (ui->checkBox_ascll_2->isChecked())
{
// ui->checkBox_hex_rece->isCheckable();
QByteArray buf = serialPort->readAll();
ui->textBrowser->append(buf);
receBytes += data.size();
}
else
{
QByteArray buf = serialPort->readAll().toHex().toUpper();
QByteArray newBA;
for (int i = 0; i< buf.length()/2 ; i++)
{
newBA.append(buf.mid(i*2,2));
newBA.append("");
}
ui->textBrowser->append(buf);
receBytes += data.size();
}

}

QString redata = QString("接收:%1").arg(QString::number(receBytes));
ui->sendlabel->setText(redata);
//显示接收信息的大小
}

QString str;
if (ui->checkBox_timestamp_send->isChecked()) {
QDateTime cur = QDateTime::currentDateTime();
//获取当前设备时间
str = cur.toString("[yy-MM-dd hh:mm:ss] ") + QString(data);
} else {
str = QString(data);
}
QString myStrTemp = QString::fromLocal8Bit(data);

if (ui->checkBox_autoline->isChecked())
{
QString str1 = ui->textBrowser->toPlainText();
str1 += myStrTemp;
//ui->textBrowser->clear();
ui->textBrowser->append(str);
}
else
ui->textBrowser->insertPlainText(str);
}

QT实现串口调试器