Problem mit CRC16 Berechnung (Hin/Rückrechnung)

OP #3197537
Lesenswert?

Hi,

ich möchte meine zu sendenden Daten über eine CRC16 absichern. Die 
crc16.h bietet mir für meinen Atmega ja schon mal einen guten 
Anhaltspunkt:
1
uint16_t U16crc;
2

3
void crc_fInit( void )
4
{
5
  U16crc = 0xffff;
6
}
7

8
void crc_fUpdate(uint8_t value)
9
{
10
  uint8_t i;
11

12
  U16crc ^= value;
13
  for (i = 0; i < 8; ++i)
14
  {
15
    if (U16crc & 1)
16
    {
17
      U16crc = (U16crc >> 1) ^ 0xA001;
18
    }
19
    else
20
    {
21
      U16crc = (U16crc >> 1);
22
    }
23
  }
24
}
Allerdings will das ganze bei mir nicht klappen.
Also, angenommen ich habe diese Nachricht:
1
unsigned char message[9] = {'M','e','s','s','a','g','e',0,0};
Dann lasse ich die CRC16 mit den Polynom 0xA001 rüberlaufen:
1
    crc_fInit();
2
    for (i=0; i<9; i++)
3
    {
4
      crc_fUpdate(message[i]);
5
    }
Als Ergebnis erhalte ich hier "54110".
Nun kopiere ich dieses Ergebnis in die letzten beiden "Zeichen"
1
    message[7] = (U16crc>>8);
2
    message[8] = (U16crc & 0xFF);
und lasse den Algorithmus erneut über die Nachricht laufen (was ja nun 
die Empfängerseite wäre):
1
    crc_fInit();
2
    for (i=0; i<9; i++)
3
    {
4
      crc_fUpdate(message[i]);
5
    }
Allerdings bekomme ich hier nicht die erwartete "0", sondern eine "7042" 
als Ausgabe.

Sehr Ihr vielleicht, wo hier der Fehler stecken könnte?

Vielen Dank im Voraus für Eure Hilfe!!!
#3197603
Lesenswert?

Oz zy schrieb:
> Nun kopiere ich dieses Ergebnis in die letzten beiden "Zeichen"

Das ist nicht ganz richtig. Berechne CRC über die Nutzdaten (7 Zeichen 
in deinem Fall) und hänge dann die CRC dran. Achte auf die richtige 
Reihenfolge.

Es gibt n+1 erprobte und fehlerfreie Implementationen im Netz. Bei 
GCC-AVR ist auch eine Lib dabei. Warum das Rad neu erfinden?
OP #3197608
Lesenswert?

Hi,

erst einmal danke für Deine Antwort! Ich hatte es immer so verstanden, 
dass für die CRC zuerst so viele Nullen (in Bits) an die Nachricht, wie 
das Polynom groß ist. Über diese neu entstandene Nachricht wird dann die 
CRC-Summe gebildet. Anschließend wird an den Rahmen (dann allerdings 
ohne die Nullen) die Summe angehängt.

Ich erfinde ja auch das Rad nicht neu. Der Code, den ich oben 
geschrieben habe ist der aus der avr-lib. Ich habe nur die crc global 
gemacht, so dass sie nicht mitübergeben werden muss...

Viele Grüße
Ozzy
#3197730
Lesenswert?

Oz zy schrieb:
> Ich hatte es immer so verstanden,
> dass für die CRC zuerst so viele Nullen (in Bits) an die Nachricht, wie
> das Polynom groß ist.

Eine CRC wird über einen Bitstrom gebildet. Die Länge dieses Bitstroms 
und die Größe des CRC sind komplett unabhängig voneinander. Du könntest 
auch eine 64-Bit-CRC über 5 Bits erstellen (ohne irgendetwas auffüllen 
zu müssen). Dass die CRC-Funktionen die Bits in "Paketen" (8, 16, 32, 
... Bits) entgegennehmen, dient nur der Bequemlichkeit.
Gast #3197766
Lesenswert?

Oz zy schrieb:
> Ok, danke, dann bin ich damit schon mal schlauer. Stimmt es aber
> trotzdem, dass, wenn ich die CRC an die Nachricht anhänge und den
> Algorithmus erneut durchlaufen lasse, eine "0" rauskommen sollte?

ja, so mache ich es auch. Aber wenn ich mich recht daran erinnere denn 
errechne ich die CRC ohne die beiden 0 bytes. Könnte ich heute abend mal 
nachschauen.
OP #3197793
Lesenswert?

Sorry, da habe ich mich unglücklich ausgedrückt. Ich berechne die CRC 
über die Nachricht (ohne Anhang). Ergebnis: "31531". Diese 2 Byte hänge 
ich an die Nachricht dran, und lasse die CRC-Berechnung nun über die 
Nachricht + CRC laufen. Ergebnis: "15420" != "0"...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren