关注WeChat Official Account 南山府嵌入式获取更多精彩
我创建了一个群关注V号后加入。因为这里不允许添加二维码
代码:QT_Pr
1-QT开发串口助手需要的基本文件
在QT6开发串口助手时,通常需要以下头文件:
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QString>
#include <QByteArray>
#include <QDebug>
其中,QSerialPort
和QSerialPortInfo
是用于访问串口和串口信息的类,QString
和QByteArray
是用于处理字符串的类,QDebug
是用于输出调试信息的类。
需要注意的是,需要在.pro文件中进行引用:
QT += serialport
在.pro文件中添加该语句可以引用QT的串口库。
2-串口设置
2-1 串口扫描
2.1.1 代码设计
我们需要知道我们电脑上有哪些串口。所以需要对串口进行一个扫描的代码。
void main_frame::portNameScan(void)
{
serialPort = new QSerialPort(this);
// 扫描本机的串口,并且添加到下拉框里
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
QString portName=info.portName();
QString description=info.description();
ui->serial_numcomboBox->addItem(portName + " (" + description + ")", portName);
QListView *view = qobject_cast<QListView *>(ui->serial_numcomboBox->view());
if (view)
{
view->setMinimumWidth(180);
}
qDebug()<<portName<<description;
}
}
2.1.2 代码分析
这段代码的作用是扫描本机可用的串口,并将它们的名称和描述添加到 ui->serial_numcomboBox
下拉框中。
具体来说,代码中:
创建了一个 QSerialPort
对象 serialPort
。
通过 QSerialPortInfo::availablePorts()
静态函数获取可用的串口信息列表,并使用 foreach
循环遍历每个串口信息。
对于每个串口信息,获取其名称和描述,然后将它们作为下拉框中的一项添加到 ui->serial_numcomboBox 中。其中,addItem()
方法的第一个参数是显示在下拉框中的文本,第二个参数是该项的值。
通过 qobject_cast
函数将下拉框的视图转换为 QListView
对象,并设置视图的最小宽度为 180 像素。
使用 qDebug() 输出该串口的名称和描述。
2.1.3运行图
2.2 波特率
2.2.1 代码设计
//头文件定义
enum BaudRateType
{
BaudRateCustom = -1,
BaudRate1200 = 1200,
BaudRate2400 = 2400,
BaudRate4800 = 4800,
BaudRate9600 = 9600,
BaudRate19200 = 19200,
BaudRate38400 = 38400,
BaudRate57600 = 57600,
BaudRate115200 = 115200
};
void main_frame::serialBaundRate(void)
{
ui->serial_BaudComboBox->addItem(QStringLiteral("自定义"),BaudRateCustom);
ui->serial_BaudComboBox->addItem(QStringLiteral("1200"), BaudRate1200);
ui->serial_BaudComboBox->addItem(QStringLiteral("2400"), BaudRate2400);
ui->serial_BaudComboBox->addItem(QStringLiteral("4800"), BaudRate4800);
ui->serial_BaudComboBox->addItem(QStringLiteral("9600"), BaudRate9600);
ui->serial_BaudComboBox->addItem(QStringLiteral("19200"), BaudRate19200);
ui->serial_BaudComboBox->addItem(QStringLiteral("38400"), BaudRate38400);
ui->serial_BaudComboBox->addItem(QStringLiteral("57600"), BaudRate57600);
ui->serial_BaudComboBox->addItem(QStringLiteral("115200"), BaudRate115200);
//ui->serial_BaudComboBox->setEditable(true);
ui->serial_BaudComboBox->setCurrentIndex(8);
connect(ui->serial_BaudComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(on_serial_BaudComboBox_currentIndexChanged(int)));
}
void main_frame::on_serial_BaudComboBox_currentIndexChanged(int index)
{
if(index==0) // 如果当前选中的是第一项 "自定义"
{
ui->serial_BaudComboBox->setEditable(true); // 设置可编辑
ui->serial_BaudComboBox->setItemText(index,tr("")); // 将第一项文本设为空
}
else // 如果当前选中的不是第一项 "自定义"
{
ui->serial_BaudComboBox->setEditable(false); // 设置不可编辑
ui->serial_BaudComboBox->setItemText(0,tr("自定义")); // 将第一项文本设为 "自定义"
}
}
2.2.2 代码分析
这段代码实现了串口波特率的设置和显示,具体解释如下:
首先在串口波特率的下拉框中添加各个波特率的选项,使用addItem()
函数添加。其中第一个参数为字符串类型的波特率名称,第二个参数为整型的波特率数值。在此函数中还添加了一个自定义波特率的选项,对应的波特率数值为一个自定义的枚举类型BaudRateCustom
。
使用setEditable
()函数设置下拉框可以编辑,但是这段代码中被注释掉了。
使用setCurrentIndex
()函数设置当前显示的波特率为115200。
使用connect
()函数连接波特率下拉框的currentIndexChanged()信号和主界面的on_serial_BaudComboBox_currentIndexChanged
()槽函数,以实现在波特率改变时执行对应的操作。
槽函数 on_serial_BaudComboBox_currentIndexChanged,当 ui->serial_BaudComboBox
的当前选中项发生改变时会自动调用。该函数的作用是判断当前选中项是否为 “自定义”,如果是,则设置 ui->serial_BaudComboBox 为可编辑状态,并将第一项文本设为空;如果不是,则将 ui->serial_BaudComboBox 设为不可编辑状态,并将第一项文本设为 “自定义”。
总体来说,这段代码实现了串口波特率的显示和设置功能,并且对于自定义波特率也进行了处理。
2.2.3 运行效果图
2.3 数据位
2.3.1 代码设计
void main_frame::serialDataBits(void)
{
// QStringList dataBitsList;
// dataBitsList << "5" << "6" << "7" << "8";
// ui->serial_dataBitscomboBox->addItems(dataBitsList);
// ui->serial_dataBitscomboBox->setCurrentIndex(3);
ui->serial_dataBitscomboBox->addItem(QStringLiteral("5"), QSerialPort::Data5);
ui->serial_dataBitscomboBox->addItem(QStringLiteral("6"), QSerialPort::Data6);
ui->serial_dataBitscomboBox->addItem(QStringLiteral("7"), QSerialPort::Data7);
ui->serial_dataBitscomboBox->addItem(QStringLiteral("8"), QSerialPort::Data8);
ui->serial_dataBitscomboBox->setCurrentIndex(3); // 默认选中8位数据位
}
2.3.2 代码分析
这段代码是一个在QT的主窗口类(main_frame)中的函数,用于设置串口的数据位(data bits)的下拉菜单(QComboBox)。下面是每一行代码的作用:
第1行:定义了一个函数,函数名为serialDataBits。
第3-7行:通过addItem函数将数据位(data bits)选项添加到QComboBox中,参数1为显示的字符串,参数2为对应的数据位枚举值。
第8行:设置QComboBox默认选中的选项,这里默认选中8位数据位。
2.3.3 运行图
2.4 停止位
2.4.1 代码设计
void main_frame::serialStopBits(void)
{
// 初始化停止位列表
// QStringList stopBitsList;
// stopBitsList << "1" << "1.5" << "2";
// ui->serial_stopBitsComboBox->addItems(stopBitsList);
// ui->serial_stopBitsComboBox->setCurrentIndex(0);
// 设置停止位
ui->serial_stopBitsComboBox->addItem("1", QSerialPort::OneStop);
ui->serial_stopBitsComboBox->addItem("1.5", QSerialPort::OneAndHalfStop);
ui->serial_stopBitsComboBox->addItem("2", QSerialPort::TwoStop);
}
2.4.2 代码分析
这段代码是为QComboBox添加串口停止位的选项,其中第一个参数是显示的文本,第二个参数是对应的枚举值,用于设置串口的停止位。这里分别添加了“1”、“1.5”、“2”三种选择,对应了QSerialPort::OneStop、QSerialPort::OneAndHalfStop、QSerialPort::TwoStop三个枚举值,分别表示1位停止位、1.5位停止位和2位停止位。用户选择对应选项后,可以通过QComboBox::currentData()函数获取该选项对应的枚举值,用于设置串口的停止位。
2.4.3 运行图
2.5 校验位
2.5.1 代码设计
void main_frame::serialParityBits(void)
{
// 添加校验位选项
ui->serial_parityBitscomboBox->addItem(QStringLiteral("无校验"), QSerialPort::NoParity);
ui->serial_parityBitscomboBox->addItem(QStringLiteral("奇校验"), QSerialPort::OddParity);
ui->serial_parityBitscomboBox->addItem(QStringLiteral("偶校验"), QSerialPort::EvenParity);
ui->serial_parityBitscomboBox->addItem(QStringLiteral("标志"), QSerialPort::MarkParity);
ui->serial_parityBitscomboBox->addItem(QStringLiteral("空格"), QSerialPort::SpaceParity);
}
2.5.2 代码分析
这段代码是一个函数,名为serialParityBits,主要是用来添加串口校验位的选项。
具体来说,它使用了Qt中的QComboBox控件,并且添加了五个不同的校验位选项。这些选项分别是“无校验”(NoParity)、“奇校验”(OddParity)、“偶校验”(EvenParity)、“标志”(MarkParity)和“空格”(SpaceParity)。每个选项都有一个相应的枚举值,用于在后续的串口设置中进行标识。
2.5.3 运行图
2.6 流控制
2.6.1 代码设计
void main_frame::serialFlowControl(void)
{
// 添加流控制选项
ui->serial_flowcomboBox->addItem(tr("None"), QSerialPort::NoFlowControl);
ui->serial_flowcomboBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
ui->serial_flowcomboBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
}
2.6.2 代码分析
这段代码是在串口设置界面中添加串口流控制选项。函数名为serialFlowControl,在该函数中,使用addItem函数添加了三个选项,分别为“None”(无流控制)、“RTS/CTS”(硬件流控制)和“XON/XOFF”(软件流控制),并分别对应了三个不同的枚举值,即QSerialPort::NoFlowControl、QSerialPort::HardwareControl和QSerialPort::SoftwareControl。
2.6.3 运行图
3 打开串口
3.1代码设计
void main_frame::on_serial_openPushButton_clicked(bool checked)
{
if (checked)
{
// 设置要打开的串口的名字
serialPort->setPortName(ui->serial_numcomboBox->currentData().toString());
serialPort->setBaudRate(ui->serial_BaudComboBox->currentText().toInt());
serialPort->setDataBits(static_cast<QSerialPort::DataBits>(ui->serial_dataBitscomboBox->currentData().toInt()));
serialPort->setStopBits(static_cast<QSerialPort::StopBits>(ui->serial_stopBitsComboBox->currentData().toInt()));
//serialPort->setStopBits(ui->serial_stopBitsComboBox->currentData().value<QSerialPort::StopBits>());
serialPort->setParity(static_cast<QSerialPort::Parity>(ui->serial_parityBitscomboBox->currentData().toInt()));
serialPort->setFlowControl(static_cast<QSerialPort::FlowControl>(ui->serial_flowcomboBox->currentData().toInt()));
if (!serialPort->open(QIODevice::ReadWrite))
{
QMessageBox::about(this, "错误", "串口打开失败");
QFont *font= new QFont;
font->setPointSize(12);
return;
}
else
{
ui->serial_openPushButton->setText("关闭串口");
qDebug()<<"串口打开成功"<<serialPort->portName()<<"\n\r"
<<"波特率" << serialPort->baudRate()<<"\n\r"
<<"数据位" <<serialPort->dataBits()<<"\n\r"
<<"停止位" <<serialPort->stopBits()<<"\n\r"
<<"校验位"<<serialPort->parity()<<"\n\r"
<<"流控制" <<serialPort->flowControl()<<"\n\r";
serialChangeEnble(true);
}
}
else
{
// 关闭串口
serialPort->close();
ui->serial_openPushButton->setText("打开串口");
serialChangeEnble(false);
}
}
3.2 代码分析
这是一个串口通信程序中的槽函数,实现了打开/关闭串口、发送数据和接收数据的功能。
on_serial_openPushButton_clicked()函数是打开/关闭串口的槽函数,它在接收到按钮的点击信号时被调用。在函数中,首先获取用户在界面上设置的串口参数(如串口号、波特率、数据位、停止位、校验位和流控制等),然后通过串口对象设置这些参数。如果串口打开失败,弹出错误提示窗口;如果打开成功,则修改按钮的文本为“关闭串口”,并将串口参数显示在调试窗口中。
on_sendpushButton_clicked()函数是发送数据的槽函数,它在接收到发送按钮的点击信号时被调用。在函数中,首先将用户在界面上输入的数据转换为QByteArray类型,然后通过串口对象的write()函数发送数据。最后将发送的数据显示在界面的接收框中。
readSerial()函数是接收数据的槽函数,它在接收到串口对象的readyRead()信号时被调用。在函数中,首先通过串口对象的readAll()函数读取所有可用的数据,然后判断接收框中数据的长度是否超过了100000个字符,如果超过了就清空接收框。接着将读取的数据显示在界面的接收框中,同时将其输出到调试窗口中。注意,在接收和发送数据时要注意编码格式的问题,为了防止乱码问题,应该设计一个编码转换的问题。
总体来说,这个代码实现了基本的串口通信功能,通过界面的控件可以方便地设置串口参数和发送数据,同时也可以实时地接收串口返回的数据。
3.3 运行
注意:如果串口号字符和setPortName中的不一致,会导致串口打不开或者闪退现象。
4-接收区
4.1 清空接收区
void main_frame::on_clearReceivepushButton_clicked()
{
ui->receivetextEdit->clear();
qDebug()<<"清空接收区";
}
5 发送区
5.1 清空发送区
void main_frame::on_clearSendpushButton_clicked()
{
ui->sendtextEdit->clear();
qDebug()<<"清空发送区";
}
6 数据的发送和接收
void main_frame::on_sendpushButton_clicked()
{
/*注意在编写接收和发送时一定要注意编码格式的问题,编码不对会导致乱码的问题,
* 为了防止这个问题的出现,应该设计一个编码转换的问题*/
QByteArray data = ui->sendtextEdit->toPlainText().toUtf8();
serialPort->write(data);
ui->receivetextEdit->append(tr("发送数据:") + QString(data)+"\n");
}
void main_frame::readSerial()
{
QByteArray data = serialPort->readAll();
if(ui->receivetextEdit->toPlainText().length()>100000)
{
ui->receivetextEdit->clear();
}
ui->receivetextEdit->moveCursor(QTextCursor::End);
//ui->receivetextEdit->append(tr("接收数据:") + QString(data));
ui->receivetextEdit->insertPlainText(tr("接收数据<--: ")+QString::fromUtf8(data));
ui->receivetextEdit->insertPlainText("\n"); // 插入换行
ui->receivetextEdit->moveCursor(QTextCursor::End);
QThread::msleep(10); // 线程暂停10毫秒,以防止读取数据过快
// ui->receivetextEdit->append(tr("接收数据:") + QString(data));
qDebug()<<QString(data);
}
6.1代码分析
这是一个串口通信程序中的两个函数。第一个函数on_sendpushButton_clicked()是用来发送数据的,它将文本编辑框sendtextEdit中的文本转化为UTF-8编码的字节数组,并使用serialPort->write(data)函数将字节数组写入串口,同时在文本编辑框receivetextEdit中显示发送的数据。
第二个函数readSerial()是用来接收数据的。它使用serialPort->readAll()函数读取串口中的所有数据,并将数据显示在文本编辑框receivetextEdit中。同时,该函数在文本编辑框中插入了一个换行符,并暂停了10毫秒的时间,以防止读取数据过快导致程序崩溃。在这个函数中,也可以使用qDebug()函数将接收到的数据输出到控制台,方便调试。