# flechazo 的小知乎,欢迎大家造访啦😘
flechazo
https://www.zhihu.com/people/jiu_sheng
书接上回 QT 使用定时器
# 使用 Qt 读取电脑串口数据
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
# 设置串口
/* 搜索可用的串口,并添加到串口组合框 */
void MainWindow::SearchSerialPorts()
{
ui->comboBoxPort->clear();
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
if(ui->comboBoxPort->count()>0){
for(int idx=0; idx<ui->comboBoxPort->count(); idx++){
QString itemName = ui->comboBoxPort->itemText(idx);
QString itemCode = ui->comboBoxPort->itemData(idx, Qt::UserRole).toString();
/* do other things */
if(itemName!=info.portName()){
ui->comboBoxPort->addItem(info.portName());//+info.description());
}
}
}else{
ui->comboBoxPort->addItem(info.portName());//+info.description());
}
}
}
/* 实现软件参变量的初始化设定 */
void MainWindow::InitialSetting()
{
/* 填充串口号组合框 */
SearchSerialPorts();
/* 填充串口波特率 */
ui->comboBoxBaud->addItem("9600");
ui->comboBoxBaud->addItem("14400");
ui->comboBoxBaud->addItem("19200");
ui->comboBoxBaud->addItem("57600");
ui->comboBoxBaud->addItem("115200");
ui->comboBoxBaud->setCurrentIndex(4);
/* 填充串口数据位 */
ui->comboBoxData->addItem("7位");
ui->comboBoxData->addItem("8位");
ui->comboBoxData->addItem("9位");
ui->comboBoxData->setCurrentIndex(1);
/* 填充串口校验位 */
ui->comboBoxParity->addItem("无校验");
ui->comboBoxParity->addItem("奇校验");
ui->comboBoxParity->addItem("偶校验");
/* 填充串口停止位 */
ui->comboBoxStop->addItem("1位");
ui->comboBoxStop->addItem("1.5位");
ui->comboBoxStop->addItem("2位");
/* 为变量赋初值 */
receivedBytes=0;
transmitBytes=0;
}
# 打开串口
/* 打开串口 */ | |
void MainWindow::on_actionConnect_triggered() | |
{ | |
serialPort->setPortName(ui->comboBoxPort->currentText()); | |
if(serialPort->open(QIODevice::ReadWrite)) | |
{ | |
/* 打开串口成功 */ | |
/* 设置波特率 */ | |
serialPort->setBaudRate(ui->comboBoxBaud->currentText().toInt()); | |
/* 设置数据位数 */ | |
switch(ui->comboBoxData->currentIndex()) | |
{ | |
case 1:serialPort->setDataBits(QSerialPort::Data8);break; | |
default: break; | |
} | |
/* 设置奇偶校验 */ | |
switch(ui->comboBoxParity->currentIndex()) | |
{ | |
case 0: serialPort->setParity(QSerialPort::NoParity);break; | |
default: break; | |
} | |
/* 设置停止位 */ | |
switch(ui->comboBoxStop->currentIndex()) | |
{ | |
case 1: serialPort->setStopBits(QSerialPort::OneStop);break; | |
case 2: serialPort->setStopBits(QSerialPort::TwoStop);break; | |
default: break; | |
} | |
/* 设置流控制 */ | |
serialPort->setFlowControl(QSerialPort::NoFlowControl); | |
/* 连接槽函数 */ | |
connect(serialPort, &QSerialPort::readyRead, this, &MainWindow::ReadSerialData); | |
/* 设置控件可否使用 */ | |
ui->actionConnect->setEnabled(false); | |
ui->actionClose->setEnabled(true); | |
ui->actionRefresh->setEnabled(false); | |
} | |
else | |
{ | |
/* 打开失败提示 */ | |
QMessageBox::information(this,tr("错误"),tr("打开串口失败!"),QMessageBox::Ok); | |
} | |
} |
# 读取数据
/* 从串口接收数据 */
void MainWindow::ReadSerialData()
{
/* 用于接收超时处理 */
flechazoTime_ms = 0;
receiveflag=true;
/* 先把接收到的数据存到这里 */
rxDatas+=serialPort->readAll();
}
# 超时处理
/* 使用定时器定时处理哦https://zhuanlan.zhihu.com/p/690750411 */
void MainWindow::recievedata()
{
flechazoTime_ms++;
/* 检查是否接收到数据 并有2ms的超时 */
if((receiveflag)&&(flechazoTime_ms>=2))
{
receiveflag=false;
if(ui->checkBoxRecieve->isChecked()) //十六进制显示
{
context = rxDatas.toHex();
context = context.toUpper();
QByteArray buffer,tmp, src;
buffer = QByteArray::fromHex(context.toLatin1());
for(int i=0;i<rxDatas.size();i++){
cmdprotocolparsing.byte[i] = buffer[i];
}
vprotocolcmdparsing("",rxDatas.size());
src = context.toLatin1();
for (int i = 0; i < src.size(); i++ )
{
tmp.append(src.at(i));
if (i % 2) tmp.append(0x20);
}
context = tmp;
}
else //ASCII显示
{
context = QString::fromLocal8Bit(rxDatas);
}
QString timeStrLine="["+QDateTime::currentDateTime().toString("hh:mm:ss")+"][接收]:🐬 ";
context = timeStrLine+context;//+"\n\r";
QString content = "<span style=\" color:blue;\">"+context+"</span>";
ui->textBrowser->append(content);
receivedBytes=receivedBytes+rxDatas.size();
ui->lcdNumberRecieve->display(receivedBytes);
ui->statusbar->showMessage(tr("成功读取%1字节数据").arg(rxDatas.size()));
rxDatas.clear();
}
}
# 发送数据
void MainWindow::WriteSerialData(QString qstring_context)
{
/* 处理成16进制 */
QByteArray flechazoSend_buffer;
QString flechazoSend_msg="";
if ( qstring_context.indexOf(" ") > 0)
{
bool ok;
char data;
QStringList list;
list = qstring_context.split(" ");
for (int i = 0; i < list.count(); i++)
{
if (list.at(i) == " ")
continue;
if (list.at(i).isEmpty())
continue;
data = (char)list.at(i).toInt(&ok, 16);
if (!ok)
{
QMessageBox::information(this, tr("提示消息"), tr("输入的数据格式有错误!"), QMessageBox::Ok);
return;
}
flechazoSend_buffer.append(data);
}
flechazoSend_msg = qstring_context.toUpper();
}
else
{
QByteArray tmp, src,myqsarraydata;
myqsarraydata=qstring_context.toLatin1();
flechazoSend_buffer = QByteArray::fromHex(myqsarraydata);
src = qstring_context.toLatin1();
for (int i = 0; i < src.size(); i++ )
{
tmp.append(src.at(i));
if (i % 2) tmp.append(0x20);
}
flechazoSend_msg = tmp;
}
/* 发送数据 */
if (serialPort && serialPort->isOpen() && serialPort->isWritable())
{
qDebug()<<"**************************buf : "<<flechazoSend_buffer.toHex();
QString timeStrLine="["+QDateTime::currentDateTime().toString("hh:mm:ss")+"][发送]:🚀 ";
QString content = "<span style=\" color:red;\">"+timeStrLine +flechazoSend_msg+"\n\r</span>";
ui->textBrowser->append(content);
/* 向串口发送数据 */
serialPort->write(flechazoSend_buffer);
ui->statusbar->showMessage(tr("发送数据成功"));
/* 界面控制 */
ui->textBrowser->setTextColor(Qt::red);
transmitBytes +=flechazoSend_buffer.size();
ui->lcdNumberSend->display(transmitBytes);
}
}
# 关闭串口
/* 关闭串口 */
void MainWindow::on_actionClose_triggered()
{
serialPort->clear();
serialPort->close();
/* 设置控件可否使用 */
ui->actionConnect->setEnabled(true);
ui->actionClose->setEnabled(false);
ui->actionRefresh->setEnabled(true);
}
完结撒花🍁
大家有问题欢迎向我提问哦!