首先,在工程文件里面,
QT += serialport
在頭文件里面,
#include <QSerialPort>
1、配置打開串口
QSerialPort* myserial = new QSerialPort():
this->myserial->setPortName("COM1");//待打開的串口號
this->myserial->setBaudRate(9600,QSerialPort::AllDirections);//設置波特率;QSerialPort::AllDirections:雙工
this->myserial->setDataBits(QSerialPort::Data8);//數據位
this->myserial->setParity(QSerialPort::NoParity);//校驗位
this->myserial->setStopBits(QSerialPort::OneStop);//停止位
this->myserial->setFlowControl(QSerialPort::NoFlowControl);//流控制
this->myserial->open(QIODevice::ReadWrite);//打開串口
2、發送數據
char test[5] = {0x01,0x02,0x03,0x04,0x05};
myserial.write(test);//發送
3、接收數據
定義一個函數作為槽函數,當接收緩沖區有數據的時候回調此函數。
void ReadBuf()
{
QByteArray dataArray;
dataArray = myserial->readAll();//讀取數據
if(!dataArray.isEmpty())
{
QString str;
str = dataArray.toHex();//把數據直接轉化為16進制的字符串形式
ui->textEdit->setText(str);
}
}
此外,在打開串口函數里面關聯信號與槽。已知,當接收緩沖區有數據的時候,串口對象會發送readyRead信號。
QObject::connect(myserial,&QSerialPort::readyRead,this,&MainWindow::ReadBuf);
4、關閉串口
this->myserial->close();
備注一、自動獲取可用串口號,並設置在QComboBox中
1、需要包含頭文件
#include <QSettings>
#include <qt_windows.h>
2、自定義函數
QString getcomm(int index, QString keyorvalue)
{
HKEY hKey;
wchar_t keyname[256]; //鍵名數組
char keyvalue[256]; //鍵值數組
DWORD keysize,type,valuesize;
int indexnum;
QString commresult;
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_READ, &hKey) != 0)
{
QString error="Cannot open regedit!";
return error;
}
QString keymessage;//鍵名
QString message;
QString valuemessage;//鍵值
indexnum = index;//要讀取鍵值的索引號
keysize = sizeof(keyname);
valuesize = sizeof(keyvalue);
if (RegEnumValue(hKey, indexnum, keyname, &keysize, 0, &type, (BYTE*)keyvalue, &valuesize) == 0)
{
for (int i=0; i<(int)keysize; i++)
{
message = keyname[i];
keymessage.append(message);
}
for (int j=0; j<(int)valuesize; j++)
{
if (keyvalue[j] != 0x00)
valuemessage.append(keyvalue[j]);
}
if (keyorvalue == "key")
commresult = keymessage;
if (keyorvalue == "value")
commresult=valuemessage;
}
else
commresult = "nokey";
RegCloseKey(hKey);//關閉注冊表
return commresult;
}
3、將可用串口放在QComboBox里面
void MainWindow::InitInterface()
{
QString path = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM";
QSettings *settings = new QSettings(path, QSettings::NativeFormat);
QStringList key = settings->allKeys();
QStringList comlist;
comlist.clear();
/* 取串口名 */
for (int i=0; i<key.size(); i++)
comlist << getcomm(i, "value");
ui->comboBox->addItems(comlist);
}
PS:
1、波特率9600意思是每秒最多傳輸9600/8=1200個字節;
2、如何解決粘包:(以傳輸ascii為例)
1)、接收數據,如果數據長度剛好為協議那么長,則直接解析
2)、如果長度不正確就把此包追加到本地變量中,然后判斷根據報文頭的位置把本地變量去掉報文頭前面的數據(QString::mid)
3)、判斷長度是否足夠(並且本地變量的頭是協議頭),如果足夠則取本地變量前n個數據進行解析,並將本地變量去掉這個包;如果不是協議頭則清空此變量,再次進行循環
PS:開發流程