ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Qt生成串口通信dll过程

2021-08-26 18:31:52  阅读:166  来源: 互联网

标签:handle Qt UartDll int dll char 串口 return serialport


#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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有