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
    

    😃


Log in to reply