台达dvp16es2plc-qt串口通信协议

#ifndef DELTA_DVP_PROTOCOL_H
#define DELTA_DVP_PROTOCOL_H

#include <QByteArray>

class Delta_dvp_protocol
{
public:
    Delta_dvp_protocol() = default;


    static QByteArray set_Y_CMD_5_Bit(int slaveAddress,int address,bool isOn);
    static QByteArray set_M_CMD_5_Bit(int slaveAddress,int address,bool isOn);
    static QByteArray set_S_CMD_5_Bit(int slaveAddress,int address,bool isOn);
    static QByteArray set_T_CMD_5_Bit(int slaveAddress,int address,bool isOn);
    static QByteArray set_C_CMD_5_Bit(int slaveAddress,int address,bool isOn);

    static QByteArray read_one_address_X_Bit(int slaveAddress, int address);
    static QByteArray read_one_address_Y_Bit(int slaveAddress, int address);
    static QByteArray read_one_address_M_Bit(int slaveAddress, int address);
    static QByteArray read_one_address_S_Bit(int slaveAddress, int address);
    static QByteArray read_one_address_T_Bit(int slaveAddress, int address);
    static QByteArray read_one_address_C_Bit(int slaveAddress, int address);

    static QByteArray set_D_CMD_6_Word(int slaveAddress,int address,int value);
    static QByteArray set_T_CMD_6_Word(int slaveAddress,int address,int value);
    static QByteArray set_C_CMD_6_Word(int slaveAddress,int address,int value);
    static QByteArray set_C_CMD_6_Word_GreaterThan199(int slaveAddress,int address,int value);

    static QByteArray read_one_address_D_Word(int slaveAddress, int address);
    static QByteArray read_one_address_T_Word(int slaveAddress, int address);
    static QByteArray read_one_address_C_Word(int slaveAddress, int address);

    static QByteArray set_M_Y_S_T_C_CMD_5_Bit(int slaveAddress,int address,bool isOn,const QString & innerDeviceName);
    static QByteArray set_M_Y_S_T_C_CMD_F_Bit(int slaveAddress, int address, bool isOn, const QString & innerDeviceName);

    static QByteArray set_D_T_CMD_6_Word(int slaveAddress,int address,int value, const QString & innerDeviceName);

    static QByteArray read_one_address_D_T_Word(int slaveAddress,int address,const QString & innerDeviceName);
    static QByteArray read_one_address_Y_M_S_T_C_X_Bit(int slaveAddress, int address,const QString & innerDeviceName);

    static void parsingReceiveData(const QByteArray & data);

};

#endif // DELTA_DVP_PROTOCOL_H
#include "delta_dvp_protocol.h"
#include <QDebug>

QList<uchar> getAsciiCodes(int num)
{
    QList<uchar> asciiCodes;
    QString hexStr = QString("%1").arg(num, 2, 16, QLatin1Char('0')).toUpper(); // 转换为两位十六进制字符串

    for (const auto & digit : hexStr)
    {
        asciiCodes.append(digit.toUpper().toLatin1());
    }
    return asciiCodes;
}

quint8 getLRC(const QByteArray &buf)
{
    quint8 check = 0; // 校验字节 初始化
    for (const auto & byte : buf)
    {
        check += byte; // 累加求和
    }
    return static_cast<quint8>((check ^ 0xFF) + 1);
}

QString parseHexString(const QString& hexString)
{
    return QString(QByteArray::fromHex(hexString.toUtf8()));
}

QString charToBinaryString(char num)
{
    QString binaryString;
    for (int i = 3; i >= 0; --i)
    {
        binaryString.append(((num >> i) & 1) ? '1' : '0');
    }
    return binaryString;
}

int get_M_Address(int address)
{
    int _address_ = 0;
    if(address >= 0 && address <= 255)
    {
        _address_ = address + 0x0800;
    }
    else if(address >= 256 && address <= 511)
    {
        _address_ = (address - 256) + 0x0900;
    }
    else if(address >= 512 && address <= 767)
    {
        _address_ = (address - 512) + 0x0A00;
    }
    else if(address >= 768 && address <= 1023)
    {
        _address_ = (address - 768) + 0x0B00;
    }
    else if(address >= 1024 && address <= 1279)
    {
        _address_ = (address - 1024) + 0x0C00;
    }
    else if(address >= 1280 && address <= 1535)
    {
        _address_ = (address - 1280) + 0x0D00;
    }
    else if(address >= 1536 && address <= 1791)
    {
        _address_ = (address - 1536) + 0xB000;
    }
    else if(address >= 1792 && address <= 2047)
    {
        _address_ = (address - 1792) + 0xB100;
    }
    else if(address >= 2048 && address <= 2303)
    {
        _address_ = (address - 2048) + 0xB200;
    }
    else if(address >= 2304 && address <= 2559)
    {
        _address_ = (address - 2304) + 0xB300;
    }
    else if(address >= 2560 && address <= 2815)
    {
        _address_ = (address - 2560) + 0xB400;
    }
    else if(address >= 2816 && address <= 3071)
    {
        _address_ = (address - 2816) + 0xB500;
    }
    else if(address >= 3072 && address <= 3327)
    {
        _address_ = (address - 3072) + 0xB600;
    }
    else if(address >= 3328 && address <= 3583)
    {
        _address_ = (address - 3328) + 0xB700;
    }
    else if(address >= 3584 && address <= 3839)
    {
        _address_ = (address - 3584) + 0xB800;
    }
    else if(address >= 3840 && address <= 4095)
    {
        _address_ = (address - 3840) + 0xB900;
    }

    return _address_;
}

int getRealAddress(int address,const QString & innerDeviceName)
{
    int _address_{0};
    if(innerDeviceName == QStringLiteral("M"))
    {
        _address_ = get_M_Address(address);
    }
    else if(innerDeviceName == QStringLiteral("Y"))
    {
        _address_ = address + 0x0500;
    }
    else if(innerDeviceName == QStringLiteral("S"))
    {
        _address_ = address;
    }
    else if(innerDeviceName == QStringLiteral("T"))
    {
        _address_ = address + 0x0600;
    }
    else if(innerDeviceName == QStringLiteral("C"))
    {
        _address_ = address + 0x0E00;
    }
    else if(innerDeviceName == QStringLiteral("X"))
    {
        _address_ = address + 0x0400;
    }
    else if(innerDeviceName == QStringLiteral("D"))
    {
        if(address >= 0 && address <= 4095)
        {
            _address_ = address + 0x1000;
        }
        else
        {
            _address_ = (address - 4096) + 0x9000;
        }
    }

    return _address_;
}

QByteArray Delta_dvp_protocol::set_M_Y_S_T_C_CMD_F_Bit(int slaveAddress,int address,bool isOn,const QString & innerDeviceName)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //0F
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x46));

    int _address_ = getRealAddress(address,innerDeviceName);

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));

    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x31));

    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x31));

    data.append(static_cast<char>(0x30));

    if(isOn)
    {
        data.append(static_cast<char>(0x31));
    }
    else
    {
        data.append(static_cast<char>(0x30));
    }

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "0F" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper() +
                      "000101";

        if(isOn)
        {
            src.append("01");
        }
        else
        {
            src.append("00");
        }

        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));

    return data;
}

QByteArray Delta_dvp_protocol::set_D_T_CMD_6_Word(int slaveAddress, int address, int value, const QString &innerDeviceName)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //06
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x36));

    int _address_ = getRealAddress(address,innerDeviceName);

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(value/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(value%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "06" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper() +
                      QString("%1").arg(value, 4, 16, QLatin1Char('0')).toUpper();

        qDebug()<<"src = "<<src;
        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));

    qDebug()<<QString(data.toHex());
    return data;
}

QByteArray Delta_dvp_protocol::read_one_address_D_T_Word(int slaveAddress, int address, const QString &innerDeviceName)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //03
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x33));

    int _address_ = getRealAddress(address,innerDeviceName);

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    //读取个数:1
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x31));

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "03" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper();
        src.append("0001");
        qDebug()<<"src = "<<src;
        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));
    qDebug()<<QString(data.toHex());

    return data;
}

QByteArray Delta_dvp_protocol::set_Y_CMD_5_Bit(int slaveAddress, int address, bool isOn)
{
    return set_M_Y_S_T_C_CMD_5_Bit(slaveAddress,address,isOn,QStringLiteral("Y"));
}

QByteArray Delta_dvp_protocol::set_M_CMD_5_Bit(int slaveAddress,int address,bool isOn)
{
    return set_M_Y_S_T_C_CMD_5_Bit(slaveAddress,address,isOn,QStringLiteral("M"));
}

QByteArray Delta_dvp_protocol::set_S_CMD_5_Bit(int slaveAddress, int address, bool isOn)
{
    return set_M_Y_S_T_C_CMD_5_Bit(slaveAddress,address,isOn,QStringLiteral("S"));
}

QByteArray Delta_dvp_protocol::set_T_CMD_5_Bit(int slaveAddress, int address, bool isOn)
{
    return set_M_Y_S_T_C_CMD_5_Bit(slaveAddress,address,isOn,QStringLiteral("T"));
}

QByteArray Delta_dvp_protocol::set_C_CMD_5_Bit(int slaveAddress, int address, bool isOn)
{
    return set_M_Y_S_T_C_CMD_5_Bit(slaveAddress,address,isOn,QStringLiteral("C"));
}

QByteArray Delta_dvp_protocol::read_one_address_X_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("X"));
}

QByteArray Delta_dvp_protocol::read_one_address_Y_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("Y"));
}

QByteArray Delta_dvp_protocol::read_one_address_M_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("M"));
}

QByteArray Delta_dvp_protocol::read_one_address_S_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("S"));
}

QByteArray Delta_dvp_protocol::read_one_address_T_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("T"));
}

QByteArray Delta_dvp_protocol::read_one_address_C_Bit(int slaveAddress, int address)
{
    return read_one_address_Y_M_S_T_C_X_Bit(slaveAddress,address,QStringLiteral("C"));
}

QByteArray Delta_dvp_protocol::set_D_CMD_6_Word(int slaveAddress, int address, int value)
{
    return set_D_T_CMD_6_Word(slaveAddress,address,value,QStringLiteral("D"));
}

QByteArray Delta_dvp_protocol::set_T_CMD_6_Word(int slaveAddress, int address, int value)
{
    return set_D_T_CMD_6_Word(slaveAddress,address,value,QStringLiteral("T"));
}

//C寄存器word0-199是16位int,之后是32位int
QByteArray Delta_dvp_protocol::set_C_CMD_6_Word(int slaveAddress, int address, int value)
{
    if(address > 199)
        return set_C_CMD_6_Word_GreaterThan199(slaveAddress,address,value);
    else
        return set_D_T_CMD_6_Word(slaveAddress,address,value,QStringLiteral("C"));
}

QByteArray Delta_dvp_protocol::set_C_CMD_6_Word_GreaterThan199(int slaveAddress, int address, int value)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //06
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x36));

    int _address_ = getRealAddress(address,QStringLiteral("C"));

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes((value >> 24) & 0xFF);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes((value >> 16) & 0xFF);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes((value >> 8) & 0xFF);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(value & 0xFF);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "06" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper() +
                      QString("%1").arg(value, 8, 16, QLatin1Char('0')).toUpper();
        ;

        qDebug()<<"src = "<<src;
        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));

    qDebug()<<QString(data.toHex());
    return data;
}

QByteArray Delta_dvp_protocol::read_one_address_D_Word(int slaveAddress, int address)
{
    return read_one_address_D_T_Word(slaveAddress,address,QStringLiteral("D"));
}

QByteArray Delta_dvp_protocol::read_one_address_T_Word(int slaveAddress, int address)
{
    return read_one_address_D_T_Word(slaveAddress,address,QStringLiteral("T"));
}

QByteArray Delta_dvp_protocol::read_one_address_C_Word(int slaveAddress, int address)
{
    return read_one_address_D_T_Word(slaveAddress,address,QStringLiteral("C"));
}

QByteArray Delta_dvp_protocol::set_M_Y_S_T_C_CMD_5_Bit(int slaveAddress, int address, bool isOn, const QString &innerDeviceName)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //05
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x35));

    int _address_ = getRealAddress(address,innerDeviceName);

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    if(isOn)
    {
        data.append(static_cast<char>(0x46));
        data.append(static_cast<char>(0x46));
    }
    else
    {
        data.append(static_cast<char>(0x30));
        data.append(static_cast<char>(0x30));
    }
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "05" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper();
        if(isOn)
        {
            src.append("FF");
        }
        else
        {
            src.append("00");
        }
        src.append("00");
        qDebug()<<"src = "<<src;
        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));
    qDebug()<<QString(data.toHex());
    return data;
}

QByteArray Delta_dvp_protocol::read_one_address_Y_M_S_T_C_X_Bit(int slaveAddress, int address, const QString &innerDeviceName)
{
    QByteArray data;
    data.append(static_cast<char>(0x3a));//ASCII码::

    //从站号 1-255 即0x01-0xff
    auto addressList = getAsciiCodes(slaveAddress);
    data.append(static_cast<char>(addressList.at(0)));
    data.append(static_cast<char>(addressList.at(1)));
    //02
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x32));

    int _address_ = getRealAddress(address,innerDeviceName);

    auto list = getAsciiCodes(_address_/256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    list = getAsciiCodes(_address_%256);
    data.append(static_cast<char>(list.at(0)));
    data.append(static_cast<char>(list.at(1)));

    //读取个数:1
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x30));
    data.append(static_cast<char>(0x31));

    {
        QString src = QString("%1").arg(slaveAddress, 2, 10, QLatin1Char('0')) +
                      "02" +
                      QString("%1").arg(_address_, 4, 16, QLatin1Char('0')).toUpper();
        src.append("0001");
        qDebug()<<"src = "<<src;
        uchar lrc = getLRC(QByteArray::fromHex(qPrintable(src)));

        list = getAsciiCodes(lrc);
        data.append(static_cast<char>(list.at(0)));
        data.append(static_cast<char>(list.at(1)));
    }

    data.append(static_cast<char>(0x0D));
    data.append(static_cast<char>(0x0A));
    qDebug()<<QString(data.toHex());

    return data;
}

void Delta_dvp_protocol::parsingReceiveData(const QByteArray &data)
{
    qDebug() <<"读取到:"<< parseHexString(data.toHex());
    qDebug() <<"data size = "<<data.size();

    // for(int i = 0;i < data.size();++i)
    // {
    //     qDebug()<<"i = "<<i<<" "<<QString(QChar(data[i]));
    // }

    auto cmd = data.mid(3,2);
    if(cmd == QByteArrayLiteral("02"))
    {
        qDebug()<<"读取bit";
        char value = data[8];
        qDebug()<<"value = "<<QString(QChar(value))<<QString(value).toInt(nullptr,16);
        QString binaryString = charToBinaryString(QString(value).toInt(nullptr,16)); // 将数值转换为二进制字符串,确保长度为4位
        qDebug()<<"binaryString = "<<binaryString;

        if (binaryString[3] == QLatin1Char('1'))
        {
            qDebug() << "解析为 on";
        }
        else
        {
            qDebug() << "解析为off";
        }
    }
    else if(cmd == QByteArrayLiteral("03"))
    {
        qDebug()<<"读取wold";
        if(data.size() == 19)//是读取C寄存器的200-255地址
        {
            auto value = data.mid(7,8);
            int decimalValue = QString(value).toInt(nullptr, 16);
            qDebug() <<"读取到值:"<< decimalValue;
        }
        else
        {
            auto value = data.mid(7,4);
            int decimalValue = QString(value).toInt(nullptr, 16);
            qDebug() <<"读取到值:"<< decimalValue;
        }
    }
}

/*
测试使用设备地址范围:
T:0-367(16F)
D:0-9999
C:0-255
*/

测试程序:https://download.csdn.net/download/kenfan1647/88791785