Ich verbinde mich mit einem Gerät über eine serielle Schnittstelle. Das Gerät fügt ein CRC16-Tag an das Ende des Datenpakets im Big-Endian-Modus an. In der Software-Seite ist der CRC-Code zu überprüfen, so etwas wie diese:CRC16 modbus Berechnung gibt falschen Wert für lange Datenpakete zurück
bool Protocol::checkCRC(const QByteArray &buf) {
if(buf.size()<3){
return false;
}
int len = buf.size()-2; // Exclude CRC token
quint16 crc = 0xFFFF;
quint16 claim = static_cast<uchar>(buf.at(buf.size()-1));
claim*=0x100;
claim+=static_cast<uchar>(buf.at(buf.size()-2));
for (int pos = 0; pos < len; pos++)
{
crc ^= (quint16)buf[pos]; // XOR byte into LSB of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
return crc==claim;
}
ich den Code aus this question kopiert.
Es funktioniert gut für kleine Pakete. Zum Beispiel folgendes Datenpaket wird in CRC16 Check mit dieser Funktion übergeben:
0x04, 0x10, 0x00, 0x3d, 0xc1
CRC Angegeben ist 0xC13D
und Funktion berechnet 0xC13D
auch. Aber für große Datenpakete (in meinem Fall 53 Bytes) nicht die Funktion korrekt CRC berechnen:
0x34, 0x02, 0x02, 0x08, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x0a, 0xdf, 0x07, 0x0a, 0x39,
0x1b, 0x02, 0x02, 0x79, 0x61, 0xbf, 0x34, 0xdd,
0x0b, 0x83, 0x0f, 0x10, 0x03, 0x1b, 0x11, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfc, 0x98
Berichtet CRC 0x98FC
ist aber berechneter Wert 0xDFC4
.
von Qt-Quellen: 'typedef unsigned short quint16' trotz der Tatsache,' QByteArray' hält 'char's sollte es funktionieren. Das Problem war 'quint16' Umwandlung in' crc^= (quint16) buf [pos] 'das sollte' quint8' sein. –
Ah, richtig, in der Tat spielt die Signedness von quint16 keine Rolle, da der Schaden bereits eine ist Das Zeichen mit Vorzeichen wird in einen größeren Typ konvertiert. Das '(quint8)' macht es unsigniert, bevor es in einen größeren Typ konvertiert wird. –