ich probiere nun sein 2 Wochen einen Code zum berechnen einer CRC8-Prüfsumme zu schreiben. Die Beispiele bei wikipedia sind dabei nicht sehr hilfreich. Folgende Seite erscheint mir sehr gut, aber trotzdem kommt bei mir nie das richtige Ergebnis heraus: Sunshine's Homepage - Understanding CRC
Ich habe mir ein einfaches Beispiel erstellt:
Bitfolge: 10110001 01011101 00000000 (24 Bit)
CRC8-Polynom: 100101111
Bei der Polynomdivision müsste am Ende 00001101 herauskommen. Mein Arduino spuckt mir aber jedes Mal einen neuen Wert aus. Findet irgendjemand meinen Denkfehler im Code? Ich wäre echt dankbar, wenn jemand den Knoten in meinem Kopf lösen könnte, da ich hier sonst noch verrückt werde.
PS: Mein Code ist angelehnt an das Kapitel 4.1 "Simple CRC-8 shift register implementation for one byte input data" aus dem aufgeführten Link.
Also Du möchtest eine 8-Bit CRC aus diesen drei Datenbytes brerechnen. was soll das Ergebnis sein?
Und hast Du die zwei oder drei wichtigsten 8-Bit CRC Berechnungsvorschriften mal daraufhin getestet, ob "Deine" CRC-Berechnung vielleicht darunter ist? Für gängige CRC Prüfsummen braucht man nämlich überhaupt keinen neuen Code zu schreiben, weil es den Code für die gängigen CRCs schon seit circa 40-50 Jahren gibt.
Und "gängig" sind "die gängigen CRC-Berechnungen" deshalb, weil sie immer wieder verwendet werden, und sich nicht jeder für irgendwelchen Pillepalle eine neue Variation einfallen läßt.
Das Ergebnis soll wie bereits erwähnt 00001101 sein. Eigentlich möchte ich das Ergebnis aus den ersten 2 Datenbytes berechnen, aber bei einem CRC 8 Polynom müssen für die Polynomdivision noch 8 Nullen an die Nutzdaten angehängt werden.
Und ja, ich habe nach bereits bestehenden Codes gesucht, aber nichts zu meinem speziellen Polynom gefunden. Das Polynom ist auch definitv 100101111. Ich kann dies nicht ändern.
Wenn der Code für 2 Bytes funktioniert möchte ich ihn für mein Problem mit mehr Bytes anpassen. Aber da ich mir das Beispiel für die Code Kontrolle per Hand berechne, möchte ich erstmal bei 2 Bytes bleiben.
jurs:
... Für gängige CRC Prüfsummen braucht man nämlich überhaupt keinen neuen Code zu schreiben, weil es den Code für die gängigen CRCs schon seit circa 40-50 Jahren gibt.
Und "gängig" sind "die gängigen CRC-Berechnungen" deshalb, weil sie immer wieder verwendet werden, und sich nicht jeder für irgendwelchen Pillepalle eine neue Variation einfallen läßt.
Du plädierst demnach dafür, per copy&paste zu programmieren (oder sonstwie etwas Fertiges zu nehmen), anstatt selbst etwas zu programmieren? Auch, wenn es dabei um den Spaß an der Sache oder ums Lernen geht?
Also mir würde ein Tipp helfen, was ich evtl. falsch mache. Ich habe eigene Codes ausprobiert und nachdem diese nicht wirklich funktioniert haben, habe ich nach Hilfe und Anregungen im Internet gesucht. Dabei bin ich auf den in meinem ersten post erwähnten Link gekommen, der das Thema sehr ausführlich und gut erklärt. Ich habe weiterhin Spaß am Programmieren, bin aber bei weitem nicht der Beste darin. Daher benötige ich manchmal eben Hilfe und schäme mich auch nicht dafür. Ich bin über jeden Tipp und jede Anregung froh und dankbar
Das ist ja super, vielen Dank für deine wirklich sehr schnelle Hilfe. Die Variante mit den einzelnen Bytes ist für mein nachfolgendes Problem zwar etwas langwieriger da ich einen zusammenhängenden Bitstrom habe, aber die Aufteilung in einzelne Bytes bekomme ich auf jeden Fall hin. Nun kann ich gut schlafen und morgen weiter werkeln
Brombeerle:
Das ist ja super, vielen Dank für deine wirklich sehr schnelle Hilfe. Die Variante mit den einzelnen Bytes ist für mein nachfolgendes Problem zwar etwas langwieriger da ich einen zusammenhängenden Bitstrom habe, aber die Aufteilung in einzelne Bytes bekomme ich auf jeden Fall hin. Nun kann ich gut schlafen und morgen weiter werkeln
Na bravo, wenn's das ist und so sein soll, dann mein Glückwunsch an agmue und Dich, dass ihr den Knoten gelöst habt!
Ich hatte am späten Abend auch noch was an Code in meine Arduino-IDE kopiert, hier kompiliert und laufen lassen, aber für die von Dir genannten Input-Bytes und das Generator-Polynom bekomme ich ein anderes Ergebnis für die CRC-Prüfsumme, und zwar ist mein Ergebnis für die CRC über alle drei Bytes:
C4 hexadezinal bzw,
196 dezimal btw.
11000100 in Binärdarstellung
Edit/Nachtrag: Wenn man nur die CRC über die ersten zwei Bytes bildet, dann stimmt es und genau das macht argmue ja auch in der for-Schleife
for (byte j = 0; j < sizeof(bytes); j++)
bytes ist ein Pointer auf ein byte-Array, und sizeof() eines Pointers ist auf der Atmega-Plattform 2 Bytes, über die er die CRC-Prüfsummenbildung iteriert.
Also alles OK, CRC-Berechnung über die ersten zwei Bytes liefert 1101 als binäres Ergebnis.
Und das CRC Ergebnis über alle 3 Bytes interessiert Dich eigentlich gar nicht. Na dann gute Nacht, jetzt gehe ich auch zu Bett.
Richtig erkannt, sizeof(pointer) liefert hier zufällig den gewünschten Wert. Die Anzahl der Bytes muß zusätzlich an die Funktion übergeben werden, sonst wird das nichts.
Ich kann programmieren, was ich will, es kommt immer "Pruefsumme: 1101" raus
bool einmal = true;
#define CRC8_Polynom 0B00101111 //MSB weglassen, da 1 XOR 1 sowieso immer 0 wird
byte input[] = {0xB1, 0x5D};
void setup() {
Serial.begin(9600);
}
void loop() {
if (einmal) {
byte crc8 = Compute_CRC8_Simple(input, sizeof(input));
Serial.print("Pruefsumme: ");
Serial.println(crc8, BIN);
einmal = false;
}
}
byte Compute_CRC8_Simple(byte* zeiger, const byte laenge) {
const byte polynom = CRC8_Polynom;
byte crc = 0; /* start with 0 so first byte can be 'xored' in */
for (byte j = 0; j < laenge; j++) {
crc ^= zeiger[j]; /* XOR-in the next input byte */
for (byte i = 0; i < 8; i++) {
if ((crc & 0x80) != 0) {
crc = (byte)((crc << 1) ^ polynom);
} else {
crc <<= 1;
}
}
}
return crc;
}
Zur Erklärung für den TO: Anstatt ein Feld an die Funktion zu übergeben, wird nur der Zeiger auf das Feld übergeben. Die Länge des Feldes geht dabei "verloren", weshalb sie als eigene Konstante übergeben werden muß. Details bitte in der Fachliteratur nachlesen
Sheldon soll sich der Frage genähert haben, wurde aber durch die Dummheit seines obersten Chefs in eine Sinnkrise gestürzt. Ruhen also die Hoffnungen auf dem Doktor (Dr Who).
Damit wünsche ich einen schönen Anfang des Endes, also des Wochenendes