串口封裝
阿新 • • 發佈:2018-08-24
長度 bit 校驗 app ati slot ket sta 函數返回
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;//報文頭 voidinit();//初始化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; }
串口封裝