其他分享
首页 > 其他分享> > Qt生成串口通信dll过程

Qt生成串口通信dll过程

作者:互联网

#ifndef UARTDLL_GLOBAL_H
#define UARTDLL_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(UARTDLL_LIBRARY)
#  define UARTDLL_EXPORT Q_DECL_EXPORT
#else
#  define UARTDLL_EXPORT Q_DECL_IMPORT
#endif

#endif // UARTDLL_GLOBAL_H
View Code UARTDLL.h:
#ifndef UARTDLL_H
#define UARTDLL_H

#include "UartDll_global.h"
#include "src/CommLib.h"
using namespace std;
class UARTDLL_EXPORT UartDll: public QObject
{
public:
    static CommLib *GetClass(int handle);              //根据句柄返回对象
    static int UartCreate(int * handle);
    static int UartOpen(int handle, char * arg);
    static int UartClose(int handle);
    static int UartSend(int handle, const char* sendData, int maxSize);
    static int UartSerSend(int handle, const char* sendData, int maxSize,
                    char * readPtr, int *readSize);
    static int UartReveice(int handle, char *pRead, int * readSize);
    static int UartSetDelay(int handle, int writeDelay, int readDelay);
    static int UnInit(int handle);
    static QMap<int, CommLib*> HandleMap;
    ~UartDll();
};
/* 创建句柄 */
extern "C" UARTDLL_EXPORT int Create(int * handle);
extern "C" UARTDLL_EXPORT int Open(int handle, char * arg);
extern "C" UARTDLL_EXPORT int Close(int handle);
extern "C" UARTDLL_EXPORT int Send(int handle, const char* sendData, int maxSize);
extern "C" UARTDLL_EXPORT int SerSend(int handle, const char* sendData, int sendSize, char *readPtr, int *readSize);
extern "C" UARTDLL_EXPORT int SetDelay(int handle, int WriteDelay, int ReadDelay);
extern "C" UARTDLL_EXPORT int Reveice(int handle, char *pRead, int * readSize);
extern "C" UARTDLL_EXPORT int UnInit(int handle);
#endif // UARTDLL_H
View Code UARTDLL.cpp
#include "UartDll.h"
QMap<int, CommLib*> UartDll::HandleMap = {};
CommLib *UartDll::GetClass(int handle)
{
    if(!HandleMap.contains(handle))
        return nullptr;
    CommLib *value = HandleMap.value(handle);
    return value;
}

int UartDll::UartCreate(int *handle)
{
    CommLib *value = new CommLib();
    *handle = -1;
    if(!value)
        return -1;
    if(!HandleMap.isEmpty())
        *handle = HandleMap.lastKey() + 1;
    else
        *handle = 0;
    HandleMap.insert(*handle, value);
    return 1;
}

int UartDll::UartOpen(int handle, char *arg)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibOpen(arg);
}

int UartDll::UartClose(int handle)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibClose();
}

int UartDll::UartSend(int handle, const char *sendData, int maxSize)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibWrite(sendData, maxSize);
}

int UartDll::UartSerSend(int handle, const char *sendData, int maxSize, char *readPtr, int *readSize)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibSerSend(sendData, maxSize, readPtr, readSize);
}

int UartDll::UartReveice(int handle, char *pRead, int *readSize)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibReceive(pRead, readSize);
}

int UartDll::UartSetDelay(int handle, int writeDelay, int readDelay)
{
    CommLib *value = GetClass(handle);
    if(!value)
        return -1;
    return value->CommLibDelay(writeDelay, readDelay);
}

int UartDll::UnInit(int handle)
{
    Q_UNUSED(handle)
    if(UartDll::HandleMap.isEmpty())
        return 1;
    QMap<int, CommLib*>::Iterator it = UartDll::HandleMap.begin();
    while(it != UartDll::HandleMap.end())
    {
        CommLib *value = UartDll::HandleMap[it.key()];
        value->CommLibClose();
        delete value;
        value = nullptr;
    }
    UartDll::HandleMap.clear();
    return 1;
}

UartDll::~UartDll()
{
    if(UartDll::HandleMap.isEmpty())
        return;
    QMap<int, CommLib*>::Iterator it = UartDll::HandleMap.begin();
    while(it != UartDll::HandleMap.end())
    {
        CommLib *value = UartDll::HandleMap[it.key()];
        value->CommLibClose();
        delete value;
        value = nullptr;
    }
    UartDll::HandleMap.clear();
    return;
}


int Create(int *handle)
{
    return UartDll::UartCreate(handle);
}

int Open(int handle, char *arg)
{
    return UartDll::UartOpen(handle, arg);
}

int Close(int handle)
{
    return UartDll::UartClose(handle);
}

int Send(int handle, const char *sendData, int maxSize)
{
    return UartDll::UartSend(handle, sendData, maxSize);
}

int SerSend(int handle, const char *sendData, int sendSize, char *readPtr, int *readSize)
{
    return UartDll::UartSerSend(handle, sendData, sendSize, readPtr, readSize);
}

int SetDelay(int handle, int WriteDelay, int ReadDelay)
{
    return UartDll::UartSetDelay(handle, WriteDelay, ReadDelay);
}

int UnInit(int handle)
{
    return UartDll::UnInit(handle);
}

int Reveice(int handle, char *pRead, int *readSize)
{
    return UartDll::UartReveice(handle, pRead, readSize);
}
View Code

DllHeadPackage.h

#ifndef DLLHEADPACKAGE_H
#define DLLHEADPACKAGE_H


#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <iostream>
#include <QMap>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QObject>
#include <QString>
#include <QByteArray>
#include <QTime>
#include <QDebug>

/*****************************************
 * @作者: XuShenghai
 * @时期: 2021-08-25
 * @类名: 串口连接信息设置类
 * @功能: 设置连接串口时的相关信息
 *****************************************/
class SerialPortType
{
public:
    enum    DataBits    { Data5 = 5,Data6 = 6,Data7 = 7,Data8 = 8};
    enum    FlowControl { NoFlowControl, HardwareControl, SoftwareControl};
    enum    Parity        { NoParity, EvenParity, OddParity, SpaceParity, MarkParity};
    enum    StopBits    { OneStop, OneAndHalfStop, TwoStop};
    QString                 Port_Name;
    int                     Baud_Rate;
    DataBits                Data_Bits;
    FlowControl             Flow_Control;
    Parity                  Data_Parity;
    StopBits                Stop_Bits;
};

/* */
#endif // DLLHEADPACKAGE_H
View Code

串口通信相关类

CommLib.h
#ifndef COMMLIB_H
#define COMMLIB_H
#include "DllHeadPackage.h"
#include "src/SerialPort.h"
class CommLib : public QObject
{
    Q_OBJECT
public:
    explicit CommLib(QObject *parent=nullptr);

private:
    QSerialPort * serialport=nullptr;
    SerialPortType * serialType=nullptr;
    int ReadWriteDelay = 200;
    int ReadDelay = 10;
public:
    int CommLibOpen(char * arg);
    int CommLibClose();
    int CommLibWrite(const char *SendData, int SendSize);
    int CommLibReceive(char * pReadData, int* pReadLen);
    int CommLibSerSend(const char *SendData, int SendSize, char *pReadData, int *pReadLen);
    int CommLibDelay(int SendDelay, int ReadDelay);
};

#endif // COMMLIB_H
View Code
CommLib.cpp
#include "CommLib.h"

CommLib::CommLib(QObject *parent) : QObject(parent)
{
    serialport = new QSerialPort(this);
    serialType = new SerialPortType();
    ReadWriteDelay = 200;
    ReadDelay = 10;
    SerialPort::setReadWriteDelay(ReadWriteDelay);
}

int CommLib::CommLibOpen(char *arg)
{
    QString str(arg);
    QRegExp rx("([^,]+),");
    QStringList strList;
    int pos = 0;

    while ((pos = rx.indexIn(str, pos)) != -1)
    {
        strList << rx.cap(1);
        pos += rx.matchedLength();
        qDebug() << rx.cap(1);
    }
    serialType->Port_Name       =     strList.at(0);
    serialType->Baud_Rate       =     strList.at(1).toInt();
    serialType->Data_Bits       =     (SerialPortType::DataBits)strList.at(2).toInt();
    serialType->Flow_Control    =     (SerialPortType::FlowControl)strList.at(3).toInt();
    serialType->Data_Parity     =     (SerialPortType::Parity)strList.at(4).toInt();
    serialType->Stop_Bits       =     (SerialPortType::StopBits)strList.at(5).toInt();
    return SerialPort::UartOpen(serialport, serialType);
}

int CommLib::CommLibClose()
{
    return SerialPort::UartClose(serialport);
}

int CommLib::CommLibWrite(const char *SendData, int SendSize)
{
    return SerialPort::UartWrite(serialport, SendData, SendSize, ReadDelay);
}

int CommLib::CommLibReceive(char *pReadData, int *pReadLen)
{
    return SerialPort::UartReceive(serialport, pReadData, pReadLen, ReadDelay);
}

int CommLib::CommLibSerSend(const char *SendData, int SendSize, char *pReadData, int *pReadLen)
{
    qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>3";
    return SerialPort::UartSerSend(serialport, SendData, SendSize, pReadData, pReadLen, ReadDelay);
}

int CommLib::CommLibDelay(int SendDelay, int ReadDelay)
{
    ReadWriteDelay = SendDelay;
    this->ReadDelay = ReadDelay;
    SerialPort::setReadWriteDelay(ReadWriteDelay);
    return 1;
}
View Code
SerialPort.h
#ifndef SERIALPORT_H
#define SERIALPORT_H

#include "DllHeadPackage.h"
#include <QMutex>
#include <QMutexLocker>
class SerialPort : public QObject
{
    Q_OBJECT
public:
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:    static int UartOpen(QSerialPort * serialport, SerialPortType *type);
 * @ 参数[]
 * @ 参数[] 需要打开的串口对象,以及打开串口的相关信息
 * @ 返回[] -1打开失败, 1 打开成功
 *****************************************/
    static int UartOpen(QSerialPort * serialport, SerialPortType *type);
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:static int UartClose(QSerialPort *serialport);
 * @ 参数[] 要关闭的串口类指针
 * @ 参数[]
 * @ 返回[]-1打开失败, 1 打开成功
 *****************************************/
    static int UartClose(QSerialPort *serialport);
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:static int UartWrite(QSerialPort *serialport, const char *sendData, qint64 sendSize, int timeOut=10);
 * @ 参数[] 操作的串口类对象指针, 发送数据的指针, 发送的数据长度, 以及阻塞时长
 * @ 参数[]
 * @ 返回[]-1打开失败, 1 打开成功
 *****************************************/
    static int UartWrite(QSerialPort *serialport, const char *sendData, qint64 sendSize, int timeOut=10);
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:static int UartReceive(QSerialPort *serialport, char *pReadData, int *pReadLen, int timeOut=10);
 * @ 参数[]
 * @ 参数[]操作的串口类指针, 接收数据的指针, 返回数据长度的指针,以及接收超时
 * @ 返回[]-1打开失败, 1 打开成功
 *****************************************/
    static int UartReceive(QSerialPort *serialport, char *pReadData, int *pReadLen, int timeOut=10);
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:UartSerSend
 * @ 参数[] QSerialPort *serialport, const char* sendData, qint64 sendSize
 * @ 参数[] char * pReadData, int *pReadLen, int timeOut=10
 * @ 参数[] 操作的串口类指针, 发送的数据, 数据长度, 接收数据的指针, 返回数据长度的指针,以及接收超时
 * @ 返回[]-1打开失败, 1 打开成功
 *****************************************/
    static int UartSerSend(QSerialPort *serialport, const char* sendData, qint64 sendSize,
                           char * pReadData, int *pReadLen, int timeOut=10);

    static QByteArray ReadBuffer;
    static int ReadWriteDelay;
    static QMutex Uart_ReadWriteLock;
    static int getReadWriteDelay();
    static void setReadWriteDelay(int value);
};

#endif // SERIALPORT_H
View Code
SerialPort.cpp
#include "SerialPort.h"
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <iostream>
QByteArray SerialPort::ReadBuffer = QByteArray(1024, 0);
int SerialPort::ReadWriteDelay = 180;
QMutex SerialPort::Uart_ReadWriteLock;
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:    static int UartOpen(QSerialPort * serialport, SerialPortType *type);
 * @ 参数[]
 * @ 参数[] 需要打开的串口对象,以及打开串口的相关信息
 * @ 返回[] -1打开失败, 1 打开成功
 *****************************************/
int SerialPort::UartOpen(QSerialPort *serialport, SerialPortType *type)
{
    QMutexLocker Locker(&Uart_ReadWriteLock);
    //如果串口对象指针为空,打开失败,返回-1
    if(!serialport)
        return -1;
    //如果串口信息类的指针为空,返回-1
    if(!type)
        return -1;
    serialport->close();
    serialport->setPortName         (type->Port_Name);                                  //设置端口名称
    serialport->setBaudRate         (static_cast<qint32>(type->Baud_Rate));             //设置波特率
    serialport->setDataBits         ((QSerialPort::DataBits)(type->Data_Bits));         //设置数据位
    serialport->setFlowControl      ((QSerialPort::FlowControl)(type->Flow_Control));   //设置流控
    serialport->setParity           ((QSerialPort::Parity)(type->Data_Parity));         //设置校验位
    serialport->setStopBits         ((QSerialPort::StopBits)(type->Stop_Bits));         //设置停止位
    if(serialport->open(QIODevice::ReadWrite))      // 打开串口,如果打开成功,返回1,如果打开失败,返回-1
    {
        QTime openDelay = QTime::currentTime().addMSecs(200);
        while(QTime::currentTime() < openDelay){}
        return 1;
    }
    else
        return -1;
}
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:static int UartClose(QSerialPort *serialport);
 * @ 参数[] 要关闭的串口类指针
 * @ 参数[]
 * @ 返回[]-1打开失败, 1 打开成功
 *****************************************/
int SerialPort::UartClose(QSerialPort *serialport)
{
    QMutexLocker Locker(&Uart_ReadWriteLock);
    //如果串口对象指针为空,打开失败,返回-1
    if(!serialport)
        return 1;
    serialport->close();
    return 1;
}
/*****************************************
 * @ 作者:     XuShenghai
 * @ 时间:     2021-08-25
 * @ 函数:static int UartWrite(QSerialPort *serialport, const char *sendData, qint64 sendSize, int timeOut=10);
 * @ 参数[] 操作的串口类对象指针, 发送数据的指针, 发送的数据长度, 以及阻塞时长
 * @ 参数[]
 * @ 返回[]-1发送失败, 1 发送成功
 *****************************************/
int SerialPort::UartWrite(QSerialPort *serialport, const char *sendData, qint64 sendSize, int timeOut)
{
    QMutexLocker Locker(&Uart_ReadWriteLock);
    if(!serialport)                     //如果串口对象指针为空,打开失败,返回-1
        return -1;
    if(!serialport->isOpen())           //如果串口未打开,退出返回-1
        return -1;
    if(!sendData)                       //如果发送数据的指针为空,退出返回-1
        return -1;
    qint64 writeLen = serialport->write(sendData, sendSize);
    if(writeLen < 0)
        return -1;
    while(serialport->waitForBytesWritten(timeOut))
    {}
    return 1;
}

int SerialPort::UartReceive(QSerialPort *serialport, char *pReadData, int *pReadLen, int timeOut)
{
    QMutexLocker Locker(&Uart_ReadWriteLock);
    if(!serialport)                     //如果串口对象指针为空,打开失败,返回-1
        return -1;
    if(!serialport->isOpen())           //如果串口未打开,退出返回-1
        return -1;
    int delay = ReadWriteDelay - timeOut * 2;
    QTime SendTime = QTime::currentTime().addMSecs(delay);
    while(QTime::currentTime() < SendTime){}                    //等待180毫秒
    ReadBuffer.clear();
    ReadBuffer.append(serialport->readAll());
    while(serialport->waitForReadyRead(timeOut))
    {
        ReadBuffer.append(serialport->readAll());
    }
    memset(pReadData, 0, strlen(ReadBuffer.toHex().data()) + 1);
    *pReadLen = ReadBuffer.length();
    memmove(pReadData, ReadBuffer.toHex().data(), strlen(ReadBuffer.toHex().data()));
    return 1;
}

int SerialPort::UartSerSend(QSerialPort *serialport, const char *sendData, qint64 sendSize, char *pReadData, int *pReadLen, int timeOut)
{
    if(!serialport)                     //如果串口对象指针为空,打开失败,返回-1
        return -1;
    if(!serialport->isOpen())           //如果串口未打开,退出返回-1
        return -1;
    if(SerialPort::UartWrite(serialport, sendData, sendSize, timeOut) < 0)
        return -1;
    int delay = ReadWriteDelay - timeOut * 2;
    QTime SendTime = QTime::currentTime().addMSecs(delay);
    while(QTime::currentTime() < SendTime){}                    //等待180毫秒
    ReadBuffer.clear();
    ReadBuffer.append(serialport->readAll());
    while(serialport->waitForReadyRead(timeOut))
    {
        ReadBuffer.append(serialport->readAll());
    }
    memset(pReadData, 0, strlen(ReadBuffer.toHex().data()) + 1);
    *pReadLen = ReadBuffer.length();

    memmove(pReadData, ReadBuffer.toHex().data(), strlen(ReadBuffer.toHex().data()));
//    std::cout << "data" << pReadData << "srcData:" << ReadBuffer.toHex().data() << std::endl;
    return 1;
}

int SerialPort::getReadWriteDelay()
{
    return ReadWriteDelay;
}

void SerialPort::setReadWriteDelay(int value)
{
    QMutexLocker Locker(&Uart_ReadWriteLock);
    ReadWriteDelay = value;
}
View Code

 

标签:handle,Qt,UartDll,int,dll,char,串口,return,serialport
来源: https://www.cnblogs.com/xushenghai19841013/p/15191023.html