一、关于接收不完整的问题
有时候发送的数据太多,QSerialPort::readyRead串口接收的就会不完整,使用串口监控软件可以看到数据其实都发了,但是发送的时间不一致,可能存在100毫秒以内的延时,这就导致使用QSerialPort::readyRead接收数据就不完整了
解决办法:
1、在发送的数据中增加帧头帧尾来判断接收的数据完成性,不完整就将下一条的合并一起一起判断
2、使用定时器将一段时间内的数据接收起来
以我https://blog.csdn.net/bigtree_mfc/article/details/107464313这篇博客为例子
先声明
QByteArray buffer;
QTimer *timer;//接收数据
初始化
timer = new QTimer(this);
在联机函数中
if(CurrentPort->isOpen())
{
StatusOfDock3->append("Succeesfully open the Port ");
//关闭设置菜单使能
BlueToothPortComboBox->setEnabled(false);
BaudRateComBox->setEnabled(false);
DateRateComBox->setEnabled(false);
ParityComBox->setEnabled(false);
StopBitsComBox->setEnabled(false);
ConnectBtn->setEnabled(false);
BreakBtn->setEnabled(true);
SendBtn->setEnabled(true);
}
else
{
StatusOfDock3->append("Defeatly open the port");
}
//连接信号槽
//QObject::connect(CurrentPort, &QSerialPort::readyRead, this, &QMySerialPort::Read_Data);
connect(CurrentPort,&QSerialPort::readyRead,this,[=]()
{
buffer.append(CurrentPort->readAll());//将读到的数据放入缓冲区
if(read_time == 1)//可以跟进设置,随时调整接收等待时长
{
timer->start(110);//设置100毫秒的延时
}
else if(read_time == 2)
{
timer->start(20);
}
});
connect(timer,&QTimer::timeout,this,&QMySerialPort::Read_Data);//timeout执行真正的读取操作
在Read_Data函数中
//读取接收到的数据
void QMySerialPort::Read_Data()
{
timer->stop();//关闭定时器
QByteArray buf = buffer;//读取缓冲区数据
buffer.clear();//清除缓冲区
if(!buf.isEmpty())
{
QString str = this->ReceiveInfo->toPlainText().toUtf8();
str += tr(buf);
ReceiveInfo->clear();
ReceiveInfo->append(str);
}
buf.clear();
}
问题就解决了
二、判断串口是否断开
//申明
public slots:
void SerialPortError(QSerialPort::SerialPortError error);
extern QSerialPort *CurrentPort;
//联机,可以放在on_connectButton_clicked()中
CurrentPort = new QSerialPort;
connect(CurrentPort, SIGNAL(error(QSerialPort::SerialPortError)),this, SLOT(SerialPortError(QSerialPort::SerialPortError)));
//断开联机中on_breakButton_clicked()
CurrentPort->disconnect(SIGNAL(error(QSerialPort::SerialPortError)));
//串口断开
void QMySerialPort::SerialPortError(QSerialPort::SerialPortError error)
{
if(error == QSerialPort::ResourceError)//
{
showMyMessageBox(tr("Prompt"), tr("The device serial line is disconnected."), this, MyMessageBox::Ok);
}
}