首先,在工程文件(.pro)里面,
QT += serialport
在头文件里面,
#include
1、配置打开串口
QSerialPort* myserial = new QSerialPort();
myserial->setPortName("COM1");//待打开的串口号
//如果在Linux下,需要指定路径,如:myserial->setPortName("/dev/ttySAC1");
//或QSerialPort* myserial = new QSerialPort("COM1");
myserial->setBaudRate(9600,QSerialPort::AllDirections);//设置波特率;
//QSerialPort::AllDirections:双工
myserial->setDataBits(QSerialPort::Data8);//数据位
myserial->setParity(QSerialPort::NoParity);//校验位
myserial->setStopBits(QSerialPort::OneStop);//停止位
myserial->setFlowControl(QSerialPort::NoFlowControl);//流控制
myserial->open(QIODevice::ReadWrite);//打开串口
2、发送数据
char test[5] = {0x01,0x02,0x03,0x04,0x05};
//或char test[] = {"test"};
myserial.write(test);//发送
3、接收数据
定义一个函数作为槽函数,当接收缓冲区有数据的时候回调此函数。
void ReadBuf()
{
QByteArray dataArray;
myserial->flush();//清除缓冲区
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、解析数据
QByteArray bytes = myserial->readAll();
//假设此处bytes为"test hello world!"
QString string = QString::fromUtf8(bytes);
int a = string.indexOf("test");//查找test的索引
QString str = string.mid(a,6);//返回从下标为a的位置起,6个字节长度的字符串,此处为test h
5、关闭串口
this->myserial->close();
1、需要包含头文件
#include
#include
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; icomboBox->addItems(comlist);
}
另一种简便的获取可用串口方法:
#include
ui.comboBox_com->clear();
for (int i = 0; i < QSerialPortInfo::availablePorts().size(); ++i)
{
ui.comboBox_com->addItem(QSerialPortInfo::availablePorts().at(i).portName());
}
1、波特率9600意思是每秒最多传输9600/8=1200个字节;
2、如何解决粘包:(以传输ascii为例)
1)、接收数据,如果数据长度刚好为协议那么长,则直接解析
2)、如果长度不正确就把此包追加到本地变量中,然后判断根据报文头的位置把本地变量去掉报文头前面的数据(QString::mid)
3)、判断长度是否足够(并且本地变量的头是协议头),如果足够则取本地变量前n个数据进行解析,并将本地变量去掉这个包;如果不是协议头则清空此变量,再次进行循环
参考链接:https://www.cnblogs.com/judes/p/6664782.html