crc - Verständnishilfe
-
Hallo zusammen,
ich möchte gerne über eine Serielle Schnittstelle Daten senden was soweit auch funktioniert. Die Daten will ich nun aber mittels CRC8 auf Fehler prüfen lassen.
Es ist doch so dass ich ein CRC erzeuge.. diesen dann meinen Daten hinten dranhänge.
Der Empfänger Teiler den Datenstream durch das Polynom und sollte als Rest 0 erhalten... Korrekt?Mein Code sieht wie folgt aus..
unsigned char reg=0; // Rechen-Register fuer den CRC Wert mit Initial Value 0 unsigned char crc8_bytecalc(unsigned char byte){ int i; // Schleifenzaehler char flag; // flag um das oberste Bit zu merken unsigned char polynom = 0xd5; // Generatorpolynom // gehe fuer jedes Bit der Nachricht durch for(i=0; i<8; i++) { if(reg&0x80) flag=1; else flag=0; // Teste MSB des Registers reg <<= 1; // Schiebe Register 1 Bit nach Links und if(byte&0x80) reg|=1; // Fülle das LSB mit dem naechsten Bit der Nachricht auf byte <<= 1; // nächstes Bit der Nachricht if(flag) reg ^= polynom; // falls flag==1, dann XOR mit Polynom } return reg; } unsigned char crc8_messagecalc(unsigned char *msg, int len){ int i; for(i=0; i<len; i++) { crc8_bytecalc(msg[i]); // Berechne fuer jeweils 8 Bit der Nachricht } return crc8_bytecalc(0); // die Berechnung muss um die Bitlaenge des Polynoms mit 0-Wert fortgefuehrt werden } int main(){ unsigned char crc8; // Ergebnis unsigned char message[4] = {0xAB, 0xCD, 0xEF}; // beliebige Nachricht unsigned char message2[20]; reg = 0; // Init Rechenregister crc8 = crc8_messagecalc(message,6); printf("CRC-8 ist %x\n",crc8); }
laut Online-CRC Rechner passt das ergebnis...
Aber wie prüfe ich das ganze auf der Empfänger Seite?
Ich würde jetzt folgendes machen....crc ans ende hängen...message[3]=crc8;
und das message array senden.
Auf der Empfängerseite würde ich ein Modulo machen... Array % 0x5d um den rest zu erhalten...
fall 0 dann OK fall nicht dann Fehler....
Ist mein Gedanke soweit ok?
Falls ja... wie mache ich diese Modulo Rechnung auf der Empfängerseite? Ich meine... es ist ja ein Array....danke schonmal im vorraus
-
also ich habe nie eine crc-prüfung programmiert, aber eine modulo-operation auf ein array lässt sich machen, indem man den rest des 1. bytes (oder worts, doppelworts, ...) nach links schiebt und dann mit den bits des nächsten bytes (oder ...) auffüllt und das ganze von vorne durchführt, bis irgendwann das array durchgerechnet wurde.
beispiel:
geg: 10101010 01010101 11001100 00110011 11110000 % 11111 = ? modulo: 10101010 % 11111 = 1111 rest schieben: 11110000 auffüllen: 11110101 restliche bits: 0101 11001100 00110011 11110000 modulo: 11110101 % 11111 = 11100 rest schieben: 11100000 auffüllen: 11100010 restliche bits: 1 11001100 00110011 11110000 modulo: 11100010 % 11111 = 1001 rest schieben: 10010000 auffüllen: 10011110 restliche bits: 01100 00110011 11110000 modulo: 10011110 % 11111 = 11 rest schieben: 11000000 auffüllen: 11011000 restliche bits: 0110011 11110000 modulo: 11011000 % 11111 = 11110 rest schieben: 11110000 auffüllen: 11110011 restliche bits: 0011 11110000 modulo: 11110011 % 11111 = 11010 rest schieben: 11010000 auffüllen: 11010001 restliche bits: 1 11110000 modulo: 11010001 % 11111 = 10111 rest schieben: 10111000 auffüllen: 10111111 restliche bits: 110000 modulo: 10111111 % 11111 = 101 rest schieben: 10100000 auffüllen: 10111000 restliche bits: 0 modulo: 10111000 % 11111 = 11101 rest schieben: 111010 -> nur noch 1 bit übrig, daher wird nur um 1 bit geschoben auffüllen: 111010 restliche bits: - modulo: 111010 % 11111 = 11011 probe mit windows-taschenrechner: 10101010 01010101 11001100 00110011 11110000 % 11111 = 11011