CRC-6 Berechnung



  • Hallo,
    ich stehe vor dem Problem, einen CRC-6-Algorithmus implementieren zu müssen.
    Das Polynom ist x6+x1+x^0. Leider ist das auch der Punkt, an dem mein gesichertes Wissen aufhört. Bei Wikipedia habe ich folgenden Code gefunden:

    #include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>
    #define CRC32POLY 0x04C11DB7 /* CRC-32 Polynom */
    
    int datastream[] = {1,0,0,0,1,1,0,0};
    int databits = 8;
    uint32_t crc32 = 0; /* Schieberegister */
    /*__int32 crc32 = 0; => für MS VS */
    
    int main(void)
    {
        int i;
        for (i = 0; i < databits; ++i)
            if (((crc32 & 0x80000000) ? 1 : 0) != datastream[i]) 
                 crc32 = (crc32 << 1) ^ CRC32POLY;
            else 
                 crc32 <<= 1;
        printf("0x%08X\n", crc32);
        return EXIT_SUCCESS;
    }
    

    Leider ist er nicht ganz nachvollziehbar für mich. Daher die erste Frage: Ist er überhaupt grundsätzlich anwendbar, wenn datastream länger als 8 bit ist?
    Meine Versuche, den Code anzupassen sahen bisher folgendermaßen aus:
    CRC32POLY (eigentlich CRC6POLY)=0x3 ([1]000011)
    databits=14;
    und statt 0x80000000 (1 und 32 x die 0) habe ich 0x40 (1000000) verwendet.
    Leider kommt für datastream=10000100101010 bei meiner Funktion 50 (110010) raus, es müsste aber wohl 23 (010111)sein.
    Hat vielleicht jemand eine Ahnung an welcher/n Stelle/n ich Fehler gemacht habe?
    Viele Grüße,
    Jan



  • JP schrieb:

    und statt 0x80000000 (1 und 32 x die 0) habe ich 0x40 (1000000) verwendet.

    Nein, 0x80000000 ist 1 und 31 x die 0 (sonst wuerde es ja gar nicht in einen unsigned int passen). Deshalb wuerde ich auch nicht 1000000 sondern 100000 verwenden.
    Das ist mir nur gerade aufgefallen, habe mir nicht ueberlegt, ob der Rest stimmt. Aber ich wuerde vorschlagen, dass du dir zuerst ansiehst wie CRC funktioniert. Wenn du das verstanden hast ist es nicht mehr schwierig, den CRC6 mit deinem Polynom zu implementieren.



  • JP schrieb:

    Hallo,
    ich stehe vor dem Problem, einen CRC-6-Algorithmus implementieren zu müssen.
    Das Polynom ist x6+x1+x^0.

    static inline unsigned crc6bit(unsigned state, unsigned bit)
    {
      bit = ((state >> 5) ^ bit) & 1;
      return ((state << 1) & 0x3F) ^ (-bit & 0x03);
    }
    

    "state" ist das 6-bittige Schieberegister
    "bit" ist das neue Bit, was den Zustand verändert
    "0x3F" ist eine Maske für die unteren 6 Bits
    "0x03" ist das Polynom ohne x^6

    bit --->[x]-------------------------------+-------+
             A                                |       |
             |                                V       |
            [T]<---[T]<---[T]<---[T]<---[T]<-[x]-[T]<-+
    

    "[T]" ist ein Bit des Schieberegisters
    "[x]" steht für XOR
    A,V,<,> sind Pfeilspitzen



  • JP schrieb:

    Hat vielleicht jemand eine Ahnung an welcher/n Stelle/n ich Fehler gemacht habe?

    Ja, hier:

    JP schrieb:

    und statt 0x80000000 (1 und 32 x die 0) habe ich 0x40 (1000000) verwendet.

    0x8000000 ist eine Maske für das oberste Bit. In einem 6-Bit Schieberegister ist das 0x20 und nicht 0x40. Ich hatte diesen Teil in crc6bit durch ">>5" geregelt.

    Ich vergaß zu sagen, dass die Funktion (crc6bit) den neuen Zustand des Schieberegisters zurückgibt. Man würde es so anwenden:

    int main(void) {
      unsigned crc6 = 0;
      crc6 = crc6bit(crc6,0);
      crc6 = crc6bit(crc6,1);
      crc6 = crc6bit(crc6,1);
      crc6 = crc6bit(crc6,0);
      crc6 = crc6bit(crc6,1);
      crc6 = crc6bit(crc6,0);
      crc6 = crc6bit(crc6,1);
      crc6 = crc6bit(crc6,0);
      printf("0x%02X\n", crc6);
      return 0;
    }
    

Anmelden zum Antworten