首页 > 解决方案 > 这个校验和是如何计算的?

问题描述

朋友们好日子。我正在使用 Qt C++,但在计算串行通信协议的校验和时遇到了问题。我对串行编程非常陌生,根据他们的文档,这有点超出我的知识。

Communication format

Head  Address    CID   Datalength Data Check    Tail

0x7E  0x01~0x0e  0x01  -          -    checksum 0x0D 

头部永远不会改变,地址可以改变,CID是一个命令我不明白如何计算数据长度校验和我不清楚他们如何计算它。他们是否采用前 5 个字节然后计算校验和然后添加尾部?或者只有对我来说是 CID 字节的“命令”。但这没有意义。

他们用来计算校验和的函数

byte check(byte* buf, byte len)
{
    byte i, chk= 0;
    int sum = 0;
    for(i = 0; i < len; i++)
    {
        chk ^= buf[i];
        sum += buf[i];
    }
    return ((chk^sum)&0xFF);
}

我在 Qt 中写的

unsigned char MainWindow::Checksum_Check(char* buf, char len)
{
    unsigned char i, chk = 0;
    int sum = 0;
    for(i = 0; i < len; i++)
    {
        chk ^= buf[i];
        sum += buf[i];
    }
    return ((chk^sum)&0xFF);
}

所以使用 QBytearray 发送一个十六进制命令

 QByteArray Chunk("\x7E\x01\x01\x00");

    char *TestStr = Chunk.data();
    unsigned char Checksum = Checksum_Check(TestStr, Chunk.length()); // tried sizeof(char) even tried sizeof(Chunk.size())

    const char cart[] = {'\x7E', '\x01', '\x01', '\x00', checksum, '\x0D'};
    QByteArray ba4(QByteArray::fromRawData(cart, 6));
    SerialPort->write(ba4.toHex()); // Tried write(ba4); as well. 
    SerialPort->waitForBytesWritten(1000);

我在 qDebug() 中得到的是校验和“FE”命令“7E010100FE0D”

看起来正确,但设备忽略了请求。我的问题是。校验和是我正确计算的还是我遗漏了一些重要的东西?任何建议或帮助都会受到欢迎,因为我被困住了。

我已经用他们的示例命令之一检查了它:

7E 01 F2 02 FF FF FE 0D

如果我这样做:

QByteArray Chunk("\x7E\x01\xF2\x02\xFF\xFF");

char *TestStr = Chunk.data();
unsigned char Checksum = Checksum_Check(TestStr, Chunk.length());

const char cart[] = {'\x7E', '\x01', '\xF2', '\x02','\xFF', '\xFF', Checksum, '\x0D'};
QByteArray ba4(QByteArray::fromRawData(cart, 8));

QString hexvalue;
hexvalue = QString("%1").arg(CRC, 0, 16, QLatin1Char( '0' ));

qDebug() << "Checksum " << hexvalue.toUpper();
qDebug() << "Command  " << ba4.toHex().toUpper();

SerialPort->write(ba4.toHex());

给我

Checksum  "FE"
Command   "7E01F202FFFFFE0D"

哪个是对的。从事情的外观来看。但是设备仍然没有响应所以我只想验证校验和实际上是否正确生成。

文档中还有一个示例

PC software Command:
buf[0] = 0x7E; //head
buf[1] = 0x01; //addr
buf[2] = 0x01; //CID
buf[3] = 0x00; //data length
buf[4] = CHK;  //Check code
buf[5] = 0x0D; //tail

这是另一个问题。如何在 ByteArray 仍在构建时生成校验和 buf[4]。在这一点上,这对我来说没有意义。我不知道/不了解它们用于校验和的字节

任何人?谢谢

标签: c++qtioserial-port

解决方案


推荐阅读