前言
本篇文章将带大家实现串口的接收和发送功能。
一、串口数据的发送
1.串口普通发送
首先我们先从数据发送区域得到发送的字符串,QtSerialPort可以使用write函数进行数据的发送,QSerialPort的write函数接受的数据类型是QByteArray,这是因为它是Qt软件框架提供的一个二进制数据缓冲区类。在串口通信时,一般都需要发送二进制数据或者字节数组。因此,QSerialPort的write函数设计为接受QByteArray类型的数据。
首先需要得到发送区域的字符串
/*按下发送按键*/ void SerialPort::on_sendbtn_clicked() { /*得到发送数据区域的字符串*/ QString sendstring = ui->sendEdit->text(); /*将数据发送出去*/ SendData(sendstring); }
编写发送数据函数:
这里传入得到的字符串,将字符串转换为QByteArray类型的数据发送出去。
当选择了发送新行的时候SendString需要加上换行符:"\r\n"。
/*发送数据*/ void SerialPort::SendData(QString SendString) { QByteArray data; if(ui->SendNewck->isChecked()) { /*选择了发送新行*/ SendString += "\r\n"; data = QByteArray(SendString.toUtf8()); } if(ui->HexSendck->isChecked()) { /*选择了以Hex格式发送*/ data = QByteArray::fromHex(SendString.toUtf8().toHex()); } if(!ui->SendNewck->isChecked() && !ui->HexSendck->isChecked()) { /*没有选择发送新行和Hex格式*/ data = QByteArray(SendString.toUtf8()); } /*将数据发送出去*/ m_SerialPort.write(data, data.length()); /*显示当前发送的数据字节总数*/ ShowNowSendRecvSize(data, true); }
这里还需要编写一个显示当前发送的数据字节总数的函数:
这个函数是非常简单的,这里就不多讲解。
/*显示当前发送或者接收了多少字节数据*/ void SerialPort::ShowNowSendRecvSize(QString data, bool Status) { /*计算当前发送了多少字节的数据*/ int nowsize = QString(data).size(); if(Status) { Sendsize+=nowsize; /*显示当前发送了多少字节数据*/ ui->sendsizelbl->setText("Send: " + QString::number(Sendsize)); } else { Recvsize+=nowsize; /*显示当前发送了多少字节数据*/ ui->Recesizelab->setText("Send: " + QString::number(Recvsize)); } }
2.串口定时发送
这个定时发送数据其实就是开启一个定时器,当定时器时间到达后调用上面编写好的数据发送函数即可。
/*用于定时发送的定时器*/ QTimer *sendtimer = new QTimer(this); /*获取定时发送的时间*/ sendtimer->start(ui->Interval_edit->text().toInt()); connect(sendtimer, SIGNAL(timeout()), this, SLOT(Scheduled_sending()));
/*定时发送*/ void SerialPort::Scheduled_sending() { /*如果定时发送按键被按下*/ if(ui->timingsendck->isChecked()) { on_sendbtn_clicked(); } }
二、串口数据的接收
串口的数据读取直接使用readAll()函数就可以将数据一次都读取出来。
读取出来的数据是QByteArray 类型的,我们将他转换为QString类型的或者转换为hex格式的类型显示在我们的接收显示区域中。
当勾选上显示时间时使用QDateTime 获取当前的时间添加到接收到的数据前面显示出来即可。
/*读取数据*/ void SerialPort::ReadData() { /*读取串口数据*/ QByteArray data = m_SerialPort.readAll(); if(ui->HexShowck->isChecked()) { /*以Hex格式显示接收到的数据*/ ui->RecvText->insertPlainText(data.toHex(' ')); } else if(ui->RecvTimeck->isChecked()) { // 获取系统当前时间 QDateTime dateTime = QDateTime::currentDateTime(); QString TimeData ="[" + dateTime.toString("yyyy-MM-dd HH:mm:ss") + "]" + QString(data); ui->RecvText->insertPlainText(TimeData); } else if(ui->wordwrapck->isChecked()) { ui->RecvText->appendPlainText(QString(data)); } else { ui->RecvText->insertPlainText(QString(data)); } /*显示当前接收了多少字节的数据*/ ShowNowSendRecvSize(data, false); }
显示当前接收了多少字节的数据函数:
/*显示当前发送或者接收了多少字节数据*/ void SerialPort::ShowNowSendRecvSize(QString data, bool Status) { /*计算当前发送了多少字节的数据*/ int nowsize = QString(data).size(); if(Status) { Sendsize+=nowsize; /*显示当前发送了多少字节数据*/ ui->sendsizelbl->setText("Send: " + QString::number(Sendsize)); } else { Recvsize+=nowsize; /*显示当前发送了多少字节数据*/ ui->Recesizelab->setText("Send: " + QString::number(Recvsize)); } }
总结
在Qt中,使用串口进行通信需要使用QSerialPort类。QSerialPort类提供了一组用于串口通信的方法和属性,包括打开和关闭串口、读写数据、设置串口波特率和数据位、设置奇偶校验和流控制等。
串口的发送和接收需要遵循协议,以确保通信正常进行。下面是串口的发送和接收的一般流程:
打开串口,使用QSerialPort的open()方法打开串口,设置好串口的参数,如波特率、数据位、奇偶校验等。
发送数据,使用QSerialPort的write()方法将数据写入串口缓冲区中,等待发送。
接收数据,使用QSerialPort的read()方法从串口缓冲区中读取数据。一般情况下,您需要在一个循环中调用read()以读取连续的数据。
解析数据,将读取的数据解析为有意义的信息,以便进行后续处理。
关闭串口,使用QSerialPort的close()方法关闭串口。