关于#qt#的问题:用QT进行下图所示程序编写(用C++)

用QT,C++语言进行下图所示程序编写,需要分成main,packunpack,widgt三个cpp文件需要完整的编码过程,具体过程或如果有文件,都可上传。用C++写代码,图1为要求,图2为示例

img

img

img

img

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1



//模块ID(1字节)
//数据头(1字节,包含6个数据的bit0+二级IDbit0,顺序从高到低依次为:数据1bit0 数据2bit0....二级IDbit0,最高位bit7=1)
//二级ID(1字节,bit0置1)
//数据6字节(bit0置1)+干扰码6字节(交替排列)
//校验码(1字节)(数据高7位和,包括模块ID高7位+二级ID高7位+数据头高7位)
//总长度4+12=16个字节

#include <iostream>
#include <string>
using namespace std;
/**@brief 编码
  @param[in] modId 模块ID
  @param[in] subId 二级ID
  @param[in] 6字节数据
  @param[in] 6字节干扰码
  @return 编码后的字符串
  */
char* enCode( char modId, char subId, char data[], char gr[] )
{
    int k = 0;
    char* package = new char[17];
    package[16] = 0; 

    //模块ID
    package[0] = modId;

    //数据头
    char t = 0x80; 
    char m;
    //1.拼接6个数据的bit0
    for (int i = 0; i < 6; i++)
    {
        m = (data[i] & 0x01);//得到data[i]的bit0
        m = m << (6 - i);    //m左移6-i位
        t += m;
    }
    //2.拼接二级ID 的bit0
    m = (subId & 0x01);
    t += m;
    package[1] = t;

    //二级ID
    package[2] = subId | 0x01; //二级ID的bit0置1

    //数据+干扰码
    k = 3;
    for (int i = 0; i < 6; i++)
    {
        m = data[i] | 0x01; //数据的bit0置1
        package[k++] = m;
        package[k++] = gr[i]; //干扰码
    }

    //校验码 package[15] = (模块ID的高7位+二级ID的高7位+数据头的高7位之和)
    char p7 = modId & 0xfe; //提取模块ID的高7位
    char p6 = subId & 0xfe; //提取二级模块的高7位
    char p5 = package[1] & 0xfe; //数据头的高7位

    p7 = p7 >> 1; //右移1位
    p6 = p6 >> 1;
    p5 = p5 >> 1;

    package[15] = p7 + p6 + p5;

    return package;
}

/**@brief 解码
   @param[in] package 需要解码的报文
   @param[out] modID 模块ID
   @param[out] subID 二级ID
   @param[out] data 6字节数据
   @param[out] gr 6字节干扰码
   @return 解码成功返回1,否则返回0
  */
int deCode(const char* package, char* modId, char* subId, char data[], char gr[])
{
    if (strlen(package) != 16) //报文长度16
        return 0;

    
    *modId = package[0];  //模块ID
    *subId = package[2] & 0xfe;  //二级ID,bit0置0
    char head = package[1]; //数据头
    *subId = (*subId) | (head & 0x01);//head的bit0是二级ID的bit0

    head = head>> 1; //右移1位,因为原来最后1位是二级ID的bit0
    //数据部分
    int k = 14;
    for (int i = 5; i >= 0; i--)
    {
        gr[i] = package[k--];
        data[i] = package[k--] & 0xfe; //将data[i]的bit0置0
        char t = head & 0x01; //得到最后1位
        data[i] = data[i] | t; //修正data[i]的bit0
        head = head >> 1;
    }
    return 1;
}


int main()
{
    char data[] = {0x00,0x01,0x6E,0x01,0x70,00};
    char gr[] = { 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe };
    char modId = 0x12;
    char subId = 0x02;
    char* p = enCode(modId, subId, data, gr);
    printf("模块ID:%02x,二级ID:%02x,", modId & 0xff, subId & 0xff);
    cout << "原数据:" ;
    for (int i = 0; i < 6; i++)
    {
        printf("%02x ", data[i] & 0xff);
    }
    cout << "\n编码后:" << endl;
    for (int i = 0; i < 16; i++)
    {
        char t = p[i];
        printf("%02x ", (t & 0xff));
    }

    //
    cout << "\n解码后:" << endl;
    char mid = 0, sid = 0, dt[7] = { 0 }, gg[7] = { 0 };
    deCode(p, &mid, &sid, dt, gg);
    printf("模块ID:%02x\n", mid);
    printf("二级id:%02x\n", sid);
    printf("数据:");
    for (int i = 0; i < 6; i++)
        printf("%02x ", dt[i] & 0xff);
    return 0;
}


编码:

QByteArray encodePacket(quint8 moduleId, quint8 dataHeader, quint16 secondaryId, const QByteArray &data, const QByteArray &interferenceCode)
{
    // 创建一个字节数组来存储编码后的数据包
    QByteArray packet;

    // 创建一个QDataStream对象来帮助我们写入二进制数据
    QDataStream stream(&packet, QIODevice::WriteOnly);

    // 将模块ID写入数据流
    stream << moduleId;

    // 将数据头写入数据流
    stream << dataHeader;

    // 将二级ID写入数据流
    stream << secondaryId;

    // 将数据写入数据流
    stream.writeRawData(data.constData(), data.size());

    // 将干扰码写入数据流
    stream.writeRawData(interferenceCode.constData(), interferenceCode.size());

    // 计算校验码
    quint8 checkSum = calculateCheckSum(packet);

    // 将校验码写入数据流
    stream << checkSum;

    return packet;
}

解码:

bool decodePacket(const QByteArray &packet, quint8 &moduleId, quint8 &dataHeader, quint16 &secondaryId, QByteArray &data, QByteArray &interferenceCode)
{
    // 创建一个QDataStream对象来帮助我们读取二进制数据
    QDataStream stream(packet);

    // 读取模块ID
    stream >> moduleId;

    // 读取数据头
    stream >> dataHeader;
    // 读取二级ID
    stream >> secondaryId;

    // 读取数据和干扰码
    data = stream.read(6);
    interferenceCode = stream.read(6);

    // 读取校验码
    quint8 checkSum;
    stream >> checkSum;

    // 检查校验码是否有效
    return checkSum == calculateCheckSum(packet);
}

quint8 calculateCheckSum(const QByteArray &packet)
{
    // 校验码是数据高7位的和
    quint8 checkSum = 0;
    for (int i = 0; i < packet.size(); ++i)
    {
        checkSum += (packet[i] >> 1);
    }
    return checkSum;
}

就是解包和拆包呗

编码解码参考资料https://blog.csdn.net/FlushHip/article/details/82498670