对于硬件工程师,测试工程师,或者嵌入式开发者来说,都很经常接触串口通信,串口通信往往用来验证串口数据收发,以及串口协议,好的串口工具非常有助于开发效率的提升,然而更优秀的工程师,我想调试的东西应该是自己要能够写的,像串口操作这种,一般来说都不难,熟悉这一套简单的东西,往往有助于自己封装协议,设计数据传输协议。而Qt成熟的接口给我们提供了便利。当然,也有人会去找开源库,或者利用windows的接口自己从枚举到读写一步步自己实现封装。https://www.onlinedown.net/soft/10001229.htm

  • Qt的串口遍历
  • Qt的监听接口
  • Qt的读接口
  • Qt的写接口
  • Qt的同步阻塞通信
  • Qt的异步通信

Qt的串口遍历

大家打开串口通信的第一反应应该是查找串口编号,然后打开串口。Qt有着成熟的接口定义,直接一次性枚举遍历所有的串口

QList

qListSerialPortInfo = QSerialPortInfo::availablePorts;

for(int iCount = 0; iCount < qListSerialPortInfo.size; iCount++)

QSerialPort* pQSerialPort = new QSerialPort;

pQSerialPort->clear;

name = qListSerialPortInfo[iCount].portName;

TITAN_INFO(''%s:portname=%s\n'', __FUNCTION__, name.toLatin1.data);

pQSerialPort->setPortName(name);

pQSerialPort->open(QIODevice::ReadWrite);

pQSerialPort->setBaudRate;

pQSerialPort->setDataBits(QSerialPort::Data8);

pQSerialPort->setParity(QSerialPort::NoParity);

pQSerialPort->setStopBits(QSerialPort::OneStop);

if(!pQSerialPort->isOpen)

TITAN_INFO(''%s:serial port is not open\n'', __FUNCTION__);

continue;

}

当你开始对串口进行操作时,要根据单片机MCU或者你的设备下面所设置的串口信息进行设置,把串口接应上,有时候你的MCU如果不支持这些设置,那么你的设置初始化就是没用的。

Qt的监听接口

串口的监听串口,这个串口应该来说是异步通信的方式,就是readyRead之后,无论你写入数据是什么样的状态,就会不断的读取监听串口,把数据吐露出来。

connect(this->serialPort, SIGNAL(readyRead), this, SLOT(recvMsg));

connect(this->serialPort, SIGNAL(readyRead), this, SLOT(recvMsg));Qt的读接口Qt的读接口,其实也是一般操作,判断串口是否异常,然后读取数据,判断是否为空,然后进行你想要的操作

void CSerialComm::OnReadSerialDataSlot

{

if(!m_pSerialPort->isOpen)

{

emit OnVIShowMessageBoxSignal(''prom'', ''Serial communication failure'');

return;

}

QByteArray data;

data = m_pSerialPort->readAll;

//TITAN_INFO(''%s:data=%s\n'', __FUNCTION__, data.toHex.data);

if(m_nFunCode == Fun_Stop)

{

m_qstrReadSaveData = '''';

return;

}

Qt的写接口

QT的写接口,看是否要进行串口缓存清理,采用flush之后,再写入,以避免你的数据产生上下两帧的串扰

void CSerialComm::OnWriteSerialDataModeSlot(QByteArray qByteArrayWriteData, tagFunCode FunCode)

{

//TITAN_INFO(''%s:enter data=%s\n'', __FUNCTION__, qByteArrayWriteData.toHex.data);

m_nFunCode = FunCode;

m_pSerialPort->flush;

m_qstrReadSaveData = '''';

if(FunCode == Fun_Read_Histogram)

{

m_nMemCount = 0;

}

else if(FunCode == Fun_SingleWrite)

{

TITAN_INFO(''%s:single write1=%s\n'', __FUNCTION__, qByteArrayWriteData.toHex.data);

}

if(m_pSerialPort->isOpen)

m_pSerialPort->write(qByteArrayWriteData);

m_pSerialPort->flush;

// TITAN_INFO(''%s:writedata=%s\n'', __FUNCTION__, qByteArrayWriteData.toHex.data);

else

emit OnVIShowMessageBoxSignal(''promp'', ''Serial port not opened!'');

TITAN_INFO(''%s:serial port not opened!\n'', __FUNCTION__);

return;

Qt的同步阻塞通信

同步阻塞通信,效率比较低,但是能保证每一帧的数据是否有说到,对帧数据进行验证判断,这样虽然耗时,但保证了数据的正确传输,但是一般情况下是不建议进行同步阻塞通信的

bool MainWindow::GetDataFromSerialComm(const QByteArray& qWriteData, QByteArray& qReadData)

QByteArray qByeteArrayRead;

m_pSerialPort->write(qWriteData);

while(m_pSerialPort->waitForReadyRead(3000))

qByeteArrayRead = m_pSerialPort->readAll;

if(qByeteArrayRead.size > 5)

qReadData = qByeteArrayRead;

return true;

return false;

Qt的异步通信

Qt的异步通信就是采用串口的监听,对IO设备通信的不断准备读取数据

connect(m_pSerialComm->GetSerialPort, &QIODevice::readyRead, m_pSerialComm, &CSerialComm::OnReadSerialDataSlot);

这个方法效率比较高,大都数情况下都会采用这种方法通信,当然你也可以在异步通信中用信号的槽与原理实现同步阻塞通信,两者并举,非常有利于你实现业务逻辑,加强对串口的认知,在工作中起到事半功倍的效果。