常用的设置参数有:端口号、波特率、数据位、停止位、校验位、流控制
使用如下方法对各个参数进行设置:
void setPortName(const QString &name) :设置端口号
bool setBaudRate(qint32 baudRate, Directions directions = AllDirections) :设置波特率
bool setDataBits(DataBits dataBits) :设置数据位
bool setStopBits(StopBits stopBits) :设置停止位
bool setParity(Parity parity) :设置校验位
bool setFlowControl(FlowControl flowControl): 设置流控制
串口参数 |
名称 |
值 |
端口号 |
portName |
自定义,如COM1、COM2 |
波特率 |
BaudRate |
Baud1200,Baud2400,Baud4800, Baud9600, ..., UnknownBaud |
数据位 |
DataBits |
Data5, Data6, Data7, Data8, UnknownDataBits |
停止位 |
StopBits |
OneStop, OneAndHalfStop, TwoStop, UnknownStopBits |
校验位 |
Parity |
NoParity,EvenParity,OddParity,SpaceParity,MarkParity, UnknownParity |
流控制 |
FlowControl |
NoFlowControl,HardwareControl,SoftwareControl, UnknownFlowControl |
[virtual] bool QSerialPort::open(OpenMode mode),有如下几种打开模式:
Constant |
Value |
Description |
QIODevice::NotOpen |
0x0000 |
The device is not open. |
QIODevice::ReadOnly |
0x0001 |
The device is open for reading. |
QIODevice::WriteOnly |
0x0002 |
The device is open for writing. Note that this mode implies Truncate. |
QIODevice::ReadWrite |
ReadOnly | WriteOnly |
The device is open for reading and writing. |
QIODevice::Append |
0x0004 |
The device is opened in append mode so that all data is written to the end of the file. |
QIODevice::Truncate |
0x0008 |
If possible, the device is truncated before it is opened. All earlier contents of the device are lost. |
QIODevice::Text |
0x0010 |
When reading, the end-of-line terminators are translated to '\n'. When writing, the end-of-line terminators are translated to the local encoding, for example '\r\n' for Win32. |
QIODevice::Unbuffered |
0x0020 |
Any buffer in the device is bypassed. |
当串口中接收到数据时,会发送readyRead()信号,可以编写关联该信号的槽函数,来接收存储数据
接收函数:
[virtual] qint64 QSerialPort::bytesAvailable() const
qint64 QIODevice::read(char *data, qint64 maxSize)
QByteArray QIODevice::read(qint64 maxSize)
QByteArray QIODevice::readAll()
发送函数:
qint64 QIODevice::write(const char *data, qint64 maxSize)
qint64 QIODevice::write(const char *data)
qint64 QIODevice::write(const QByteArray &byteArray)
[virtual] void QSerialPort::close()
开发环境:VS2013+Qt5.9.3+Virtual Serial Port Device+串口助手
先添加一对虚拟串口,如下图:
然后使用开发的串口通信软件和串口助手进行通信,运行结果如下图:
参考代码:
SerialPortDemo.h
添加如下声明:
public:
//串口部分
QSerialPort serialPort;
bool connectFlag;
//数据存储
QString qexeFullPath;
QString fileNamePath;
QFile *file;
QByteArray buffer; //数据存储缓冲区
QByteArray recvBytes; //接收字节数
QByteArray sendBytes; //发送字节数
void Init(); //初始化
void coSignalSlot(); //关联信号和槽
void getSerialPort(); //获取串口设置的值
public slots:
//点击按钮对应的槽函数
void openSerialPort(); //打开串口
void sendMsg(); //发送数据
void saveData(); //保存数据
SerialPortDemo.cpp
SerialPort::SerialPort(QWidget *parent)
: QWidget(parent)
, file(nullptr)
, connectFlag(true)
, recvBytes(0)
, sendBytes(0)
{
ui.setupUi(this);
qexeFullPath = QCoreApplication::applicationDirPath() + "/../";
Init();
coSignalSlot();
//设置背景颜色
this->setStyleSheet(".QWidget{background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0.3 rgb(153,136,13), stop: 1 rgb(211,187,18));}");//渐变背景
ui.widget_4->setStyleSheet("QWidget{background:rgb(150,100,0)}");//状态栏
}
SerialPort::~CheckASIC()
{
//关闭串口
if (file != NULL && file->isOpen())
{
file->close();
delete file;
file = NULL;
}
}
void SerialPort::Init()
{
//初始化串口设置相关字符串
QStringList portStr, baudRateStr, dataBitsStr, stopBitsStr, parityStr, flowControlStr, instructStr;
portStr << "COM1" << "COM2" << "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8"
<< "COM9" << "COM10" << "COM11" << "COM12" << "COM13" << "COM14" << "COM15" << "COM16";
baudRateStr << "110" << "300" << "600" << "1200" << "2400" << "4800" << "9600"
<< "14400" << "19200" << "38400" << "56000" << "57600" << "119200";
dataBitsStr << "5 bit" << "6 bit" << "7 bit" << "8 bit";
stopBitsStr << "1 bit" << "1.5 bit" << "2 bit";
parityStr << "NONE" << "EVEN" << "ODD" << "MARK" << "SPACE";
flowControlStr << "None" << "Hardware" << "Software";
//初始化串口各参数列表
ui.cbBoxPort->addItems(portStr);
ui.cbBoxBaudRate->addItems(baudRateStr);
ui.cbBoxDataBits->addItems(dataBitsStr);
ui.cbBoxStopBits->addItems(stopBitsStr);
ui.cbBoxParity->addItems(parityStr);
ui.cbBoxFlowControl->addItems(flowControlStr);
//设置串口各参数的默认索引
ui.cbBoxPort->setCurrentIndex(0);
ui.cbBoxBaudRate->setCurrentIndex(12);
ui.cbBoxDataBits->setCurrentIndex(3);
ui.cbBoxStopBits->setCurrentIndex(0);
ui.cbBoxParity->setCurrentIndex(0);
ui.cbBoxFlowControl->setCurrentIndex(0);
//打开按钮样式
ui.pBtnOpenPort->setStyleSheet("QPushButton{background: #770000;color:white}");
}
//信号和槽关联
void SerialPort::coSignalSlot()
{
connect(ui.pBtnOpenPort, SIGNAL(clicked()), this, SLOT(openSerialPort()));
connect(ui.pBtnSend, SIGNAL(clicked()), this, SLOT(sendMsg()));
}
//获取串口设置值
void SerialPort::getSerialPort()
{
//设置串口名称
serialPort.setPortName(ui.cbBoxPort->currentText());
//设置波特率
qint32 baudRate = ui.cbBoxBaudRate->currentText().toInt();
serialPort.setBaudRate(baudRate);
//设置数据位
if (ui.cbBoxDataBits->currentIndex() == 3)
{
serialPort.setDataBits(QSerialPort::Data8);
}
else if (ui.cbBoxDataBits->currentIndex() == 2)
{
serialPort.setDataBits(QSerialPort::Data7);
}
else if (ui.cbBoxDataBits->currentIndex() == 1)
{
serialPort.setDataBits(QSerialPort::Data6);
}
else if (ui.cbBoxDataBits->currentIndex() == 0)
{
serialPort.setDataBits(QSerialPort::Data5);
}
//设置停止位
if (ui.cbBoxStopBits->currentIndex() == 0)
{
serialPort.setStopBits(QSerialPort::OneStop);
}
else if (ui.cbBoxStopBits->currentIndex() == 1)
{
serialPort.setStopBits(QSerialPort::OneAndHalfStop);
}
else if (ui.cbBoxStopBits->currentIndex() == 2)
{
serialPort.setStopBits(QSerialPort::TwoStop);
}
//设置校验位
if (ui.cbBoxParity->currentIndex() == 0)
{
serialPort.setParity(QSerialPort::NoParity);
}
else if (ui.cbBoxParity->currentIndex() == 1)
{
serialPort.setParity(QSerialPort::EvenParity);
}
else if (ui.cbBoxParity->currentIndex() == 2)
{
serialPort.setParity(QSerialPort::OddParity);
}
else if (ui.cbBoxParity->currentIndex() == 3)
{
serialPort.setParity(QSerialPort::MarkParity);
}
else if (ui.cbBoxParity->currentIndex() == 4)
{
serialPort.setParity(QSerialPort::SpaceParity);
}
//设置是否流控制
if (ui.cbBoxFlowControl->currentIndex() == 0)
{
serialPort.setFlowControl(QSerialPort::NoFlowControl);
}
else if (ui.cbBoxFlowControl->currentIndex() == 1)
{
serialPort.setFlowControl(QSerialPort::HardwareControl);
}
else if (ui.cbBoxFlowControl->currentIndex() == 2)
{
serialPort.setFlowControl(QSerialPort::SoftwareControl);
}
}
//打开串口
void SerialPort::openSerialPort()
{
getSerialPort();
//connectFlag默认为true,然后直接执行if中的语句,打开串口
if (connectFlag)
{
serialPort.open(QIODevice::ReadWrite);
//初始化相关变量
connectFlag = !connectFlag;
recvBytes = 0;
sendBytes = 0;
ui.pBtnOpenPort->setText("关闭串口"); //打开串口时显示关闭串口字样
ui.pBtnOpenPort->setStyleSheet("QPushButton{background: #FF0000;}"); //串口打开后,按钮变为红色
ui.widget_4->setStyleSheet("QWidget{background:rgb(0,152,0);}"); //串口打开后,状态栏变为绿色
if (file == NULL) //如果文件不存在,创建新文件,每次打开串口都创建新文件
{
QDateTime currentTime = QDateTime::currentDateTime(); //获取系统现在的时间
QString fileName = "Data_" + currentTime.toString("yyyyMMddhhmmss") + ".dat"; //以打开串口的时间命名文件
fileNamePath = qexeFullPath + "SaveData/" + fileName;
ui.labelSavePath->setText("存储路径:" + fileNamePath);
file = new QFile(fileNamePath);
if (!file->open(QIODevice::WriteOnly))
{
return;
}
}
connect(&serialPort, SIGNAL(readyRead()), this, SLOT(saveData()));//串口有数据时发射readyRead()信号
}
else
{
serialPort.close();
connectFlag = !connectFlag;
//关闭串口
if (file != NULL)
{
delete file;
file = NULL;
}
ui.pBtnOpenPort->setText("打开串口");
ui.pBtnOpenPort->setStyleSheet("QPushButton{background: #770000;color:white;}");
ui.widget_4->setStyleSheet("QWidget{background:rgb(7,152,214);}");//状态栏
}
}
//=================================数据存储部分======================================
//接收存储数据
void SerialPort::saveData()
{
if (serialPort.isOpen())
{
buffer = serialPort.readAll();//读取数据到缓冲数组中
recvBytes += buffer;
qulonglong rcvBytesLen = recvBytes.size();
ui.labelRecv->setText(" Recv:" + QString::number(rcvBytesLen));
if (buffer.size() > 0)
{
ui.plainTextEdit->appendPlainText(QString(buffer));
if (file->isOpen())
{
file->write(buffer);
file->close();
}
else
{
if (!file->open(QIODevice::WriteOnly | QIODevice::Append))
{
return;
}
file->write(buffer);
file->close();
}
}
}
}
//指令发送
void SerialPort::sendMsg()
{
if (serialPort.isOpen())
{
QString msg = ui.plainTextEdit_2->toPlainText();
serialPort.write(msg.toUtf8());//字符串转QByteArray,将数据发送到串口
QByteArray sendByte = msg.toUtf8();
sendBytes += sendByte;
qulonglong sendBytesLen = sendBytes.size();
ui.labelSend->setText(" Send:" + QString::number(sendBytesLen));
}
}