Forum: Mikrocontroller und Digitale Elektronik CRC-16 Prüfsumme (serielle Übertragung)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Olaf R. (gruser)


Lesenswert?

Hallo zusammen,

ich habe hier den untenstehenden Code gefunden zur Berechnung einer 
Checksumme (CRC-16), allerdings bekomme ich in den beiden Bytes des 
Ergebnisses jeweils nur eine "1".

Was mache ich falsch? Wenn ich aus 3 Bytes einen CRC-Wert ermitteln
möchte, muss ich die Funktion doch einfach nur 3x aufrufen:

  DEVICE_CRC16 = calcCRC16r (DEVICE_CRC16,Wert1,0xA001);
  DEVICE_CRC16 = calcCRC16r (DEVICE_CRC16,Wert2,0xA001);
  DEVICE_CRC16 = calcCRC16r (DEVICE_CRC16,Wert3,0xA001);

Die beiden Bytes frage ich mit DEVICE_CRC16.low8 bzw. DEVICE_CRC16.high8
ab. Bei den Deklarationen von Wert1-3 habe ich bereits alles probiert
(uns16/ uns8, char) - am Ergebnis hat es nichts geändert.
Außerdem glaube ich nicht dass das Polynom A001 (bzw. 
"1010000000000001") dem Polynom von CRC16 entspricht...

Kennt sich hier jemand gut aus?

Grüße
Olaf









//- calcCRC16r ------------------------------------------------------
unsigned int calcCRC16r(unsigned int crc, unsigned int c, unsigned int
mask)
{
  unsigned char i;
  for(i=0;i<8;i++)
  {
    if((crc ^ c) & 1) { crc=(crc>>1)^mask; }
    else crc>>=1;
    c>>=1;
  }
  return (crc);
}
//-------------------------------------------------------------------

Aufruf der Funktion im Programm:

{
//...
  unsigned int DEVICE_CRC16=0;
  DEVICE_CRC16 = calcCRC16r (DEVICE_CRC16,chr,0xA001);
//...
}
von so nicht (Gast)


Lesenswert?

Ja. Mein code :

PROCEDURE calcCRCbyte(data:BYTE;VAR crc:WORD);
VAR i:BYTE;
BEGIN
 FOR i:=0 TO 7 DO BEGIN
   IF ((data and $01)XOR(crc AND $0001)<>0) THEN BEGIN
     crc:=crc shr 1;
     crc:= crc XOR $A001;
    END
   ELSE BEGIN
     crc:=crc shr 1;
    END;
   data:=data shr 1;
  END;
END;

Deiner scheint etwas kuerzer zu sein, dh etwas wegzulassen.
von Michael K. (mmike)


Lesenswert?

Hier einer in C:

HEADER:
1
/*****************************************************************************
2
* Name: crcCCITT()
3
* Eingaben: - Laenge der Nachricht
4
* - Zeiger auf die Nachricht
5
* - CRC-Vorladewert, Startwert ist 0xFFFF
6
* Ausgaben: - CRC von der Nachricht
7
* Beschreibung: Die Funktion berechnet den CRC von der Nachricht nach dem
8
* Generatorpolynom g(x) = x^16+ x^12 + x^5 + 1 (CCITT-Polynom).
9
*****************************************************************************/
10
 
11
#ifndef __CRC16_H__
12
#define __CRC16_H__
13
 
14
#include <inttypes.h>
15
 
16
#define poly  0x1021    // g(x) = (x^16+) x^12 + x^5 + 1
17
 
18
uint16_t crcCCITT(uint8_t size, volatile uint8_t * mem, uint16_t crc);
19
 
20
#endif

IMPLEMENTATION:
1
uint16_t crcCCITT(uint8_t size, volatile uint8_t * mem, uint16_t crc)
2
{
3
  //  static int i,j;
4
  uint8_t i;
5
  uint8_t j;
6
 
7
  //  static unsigned short b;
8
  uint8_t b;
9
 
10
  //  static unsigned char m;
11
  uint8_t m;
12
 
13
  // While (more message bits)
14
  for (i = 0; i < size; i++)
15
  {
16
    m = mem[i];
17
    for( j = 8; j; j-- )
18
    {
19
      b = 0;
20
      if(crc & 0x8000)
21
        b++;
22
      // Shift the register left by one bit,
23
      crc <<= 1;
24
      if ((m & 0x80) != 0) crc |= 1;
25
      m <<= 1;
26
      // If (a 1 bit popped out of the register during step 3)
27
      // Register = Register XOR Poly.
28
      if (b != 0) 
29
        crc ^= poly;
30
    }
31
  }
32
  return crc;
33
}
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.