1、头文件
#ifndef MYSERIAL_H #define MYSERIAL_H#include <QSerialPort> #include "mymethod.h" class MySerial : public QSerialPort { Q_OBJECT public: MySerial(QObject *parent); ~MySerial(); private: QSerialPort* serialPort = NULL;//串口对象 QByteArray HEAD;//报文头 void init();//初始化private slots: void openSlot(SerialPortInfo serialPortInfo);//连接函数 void rcvSlot();//接收数据槽函数 void sendSlot(QByteArray ba);//发送数据槽函数 void closeSlot();//关闭槽函数 signals: void serialStateSignal(QString info);//向外发出的调试信息 void getPacketSignal(int type, QByteArray ba);//tcp将不同的包发出去 }; #endif // MYSERIAL_H
2、源文件
#include "myserial.h" MySerial::MySerial(QObject *parent) : QSerialPort(parent) { this->init(); } MySerial::~MySerial() { } /*****************************************************************/ //作者:朱小勇 //函数名称:初始化 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void MySerial::init() { HEAD.resize(2); HEAD[0] = 0x55; HEAD[1] = 0xAA; } /*****************************************************************/ //作者:朱小勇 //函数名称:打开串口 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void MySerial::openSlot(SerialPortInfo serialPortInfo) { if (NULL == serialPort) { serialPort = new QSerialPort(); QObject::connect(serialPort, SIGNAL(readyRead()), this, SLOT(rcvSlot())); } if (serialPort->isOpen()) { return; } serialPort->setPortName(serialPortInfo.portName); serialPort->setBaudRate(serialPortInfo.baudRate, QSerialPort::AllDirections); serialPort->setDataBits(serialPortInfo.dataBits);//数据位 serialPort->setParity(serialPortInfo.parity);//校验位 serialPort->setStopBits(serialPortInfo.stopBits);//停止位 serialPort->setFlowControl(QSerialPort::NoFlowControl);//流控制 if (serialPort->open(QIODevice::ReadWrite))//打开串口 { emit serialStateSignal("串口打开成功..."); } else { emit serialStateSignal("串口打开失败!!!"); } } /*****************************************************************/ //作者:朱小勇 //函数名称:接收数据 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void MySerial::rcvSlot() { static QByteArray allBa;//用来存所有文件 allBa.append(serialPort->readAll());//读取数据 int head = allBa.indexOf(HEAD);//报文头的位置 uint16_t length = 0;//存长度字节 QByteArray currentBa; int id = 0; while (-1 != head) { allBa = allBa.mid(head);//去掉报头之前的 memcpy(&length, allBa.data() + 2, 2); if (allBa.size() >= length)//长度够,进行解析 { currentBa = allBa.mid(0, length);//获取当前完成包 id = Mymethod::getPacketType(currentBa); if (-1 != id) { emit getPacketSignal(id, currentBa); } allBa = allBa.mid(2); } else { break; } head = allBa.indexOf(HEAD);//刷新报文头的位置 } } /*****************************************************************/ //作者:朱小勇 //函数名称:发送 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void MySerial::sendSlot(QByteArray ba) { if (NULL == serialPort) { emit serialStateSignal("串口未初始化!!!"); return; } if (!serialPort->isOpen()) { emit serialStateSignal("串口未打开!!!"); return; } if (ba.size() != serialPort->write(ba)) { emit serialStateSignal("指令发送失败!!!"); } else { emit serialStateSignal("发送指令成功..."); } } /*****************************************************************/ //作者:朱小勇 //函数名称:关闭 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void MySerial::closeSlot() { if (NULL == serialPort) { return; } serialPort->close(); emit serialStateSignal("已关闭串口..."); }
3、自定义函数,获取报文类型
int Mymethod::getPacketType(const QByteArray& ba) { int result = -1; uint16_t length = 0; if ((ba[0] == (char)0x55) && (ba[1] == (char)0xAA))//报文头正确 { memcpy(&length, ba.data() + 2, 2); if (length == ba.size())//长度正确 { QByteArray tempBa; tempBa.resize(ba.size() - 1); memcpy(tempBa.data(), ba.data(), ba.size() - 1); char crc = Mymethod::CRC(tempBa); if (crc == ba[ba.size() - 1])//CRC正确 { result = (int)ba[4]; } } } return result; }