CRC8 berechnen

Gast #2151377
Lesenswert?

Hallo

suche einen einfachen CRC8-Code für den MSP 430. Ich habe einen 32 Bit 
Wert. Die ersten 24 Bit sollen überprüft und mir dem Wert der letzten 8 
Bit verglichen werden. Die Checksumme soll nach SAE J1850 mit dem 
Generatorpolynom 1D und dem Initalwert 0xFF und XOR out=0xFF berechnet 
werden. Wäre echt super wenn jemand dafür ein Code-Beispiel hat.
mfg Andi
Gast #2151405
Lesenswert?

1
uint8_t CalculateCRC8Internal(uint8_t inCRC, uint8_T inByte)
2
{
3
  inByte ^= inCRC;
4
  inCRC = 0;
5
  if(inByte & 0x01) inCRC  = 0x5E;
6
  if(inByte & 0x02) inCRC ^= 0xBC;
7
  if(inByte & 0x04) inCRC ^= 0x61;
8
  if(inByte & 0x08) inCRC ^= 0xC2;
9
  if(inByte & 0x10) inCRC ^= 0x9D;
10
  if(inByte & 0x20) inCRC ^= 0x23;
11
  if(inByte & 0x40) inCRC ^= 0x46;
12
  if(inByte & 0x80) inCRC ^= 0x8C;
13
  return inCRC;
14
}
Moderator Persönliche Seite #2151576
Lesenswert?

Wenn ich den Dallas-1wire-Code aus der avr-libc:
1
    uint8_t
2
    _crc_ibutton_update(uint8_t crc, uint8_t data)
3
    {
4
        uint8_t i;
5

6
        crc = crc ^ data;
7
        for (i = 0; i < 8; i++)
8
        {
9
            if (crc & 0x01)
10
                crc = (crc >> 1) ^ 0x8C;
11
            else
12
                crc >>= 1;
13
        }
14

15
        return crc;
16
    }

mit dem SAE-J1850-Polynom vergleiche, dann solltest du diesen benutzen
können, indem du die 0x8C durch eine 0xB8 ersetzt.  Was allerdings
"XOR out=0xFF" meint, verstehe ich nicht.
Gast #2151611
Lesenswert?

Vorsicht, das Beispiel von Jörg zeigt die INVERSE -Berechnug der CRC.
Bei seriellen Übertragungen werden üblicherweise Datenbytes mit LSB 
zuerst übertragen, nur die CRC mit MSB zuerst. Um den gleichen 
Sendealgorythmus zu verwenden wird dann die CRC invers berechnet und MSB 
steht im BIT0 und alles passt wieder.

also:
Man beginnt mit crc = 0xff, führt dann mit jedem Byte die Berechnung von 
Jörg fort und und hängt am Schluss die crc invertiert (out = crc^0xff) 
an den Datenstrom an. Das hat den Vorteil dass bei einer neuerlichen 
Berechnung der CRC im Empfänger über alle Bytes (also Daten + 
invertierte CRC) ein  (für das Polynom typischer) konstanter Wert heraus 
kommt.


Viel Spass noch
Moderator Persönliche Seite #2151627
Lesenswert?

Rolle schrieb:
> Vorsicht, das Beispiel von Jörg zeigt die INVERSE -Berechnug der CRC.

Ja, wobei ich (mangels einer auf die Schnelle zu findenden Spec) davon
ausgegangen bin, dass SAE J1850 wie fast alle anderen seriellen
Übertragungen ebenfalls mit dem LSB beginnt, sodass man den Dallas-
Algorithmus 1:1 benutzen kann.

Das ist eigentliche Problem mit den CRCs, man muss nicht nur den
Startwert und das Generatorpolynom kennen, sondern auch noch die
Bitreihenfolge.  Sinnvollerweise sollte man also bei jedem praktisch
beschriebenen Algorithmus auch gleich noch eine Beispielsequenz
dabei stehen haben.
Gast #2216937
Lesenswert?

Hallo!

Ich habe ein kleines Verständnisproblem mit der Matematik hinter dieser 
Berechnung, darum habe ich versucht einen Code für eine Bit-weise 
berechnung geschrieben. Soweit sogut, nur habe ich das Problem, wenn ich 
als Startwert 0xFF am Beginn des Dataframes anhänge bekomme ich einen 
falschen CRC-Wert. Der Code wurde mit  einer Routine aus dem Netz 
verifiziert. (http://www.zorc.breitbandkatze.de/crc.html)
Dort gibt es auch die Möglichkeit den Startwert "direct" oder 
"nondirect" anzugeben. "direct" liefert das richtige Ergebnis, 
"nondirect" das gleiche Ergebniss wie mein Code.
Kan mir jemand den Unterschied erklären?
Gast #2217085
Lesenswert?

1.Methode (die da "direct" genannt wird)
Der Startwert ist der Wert den man zu Begin einer Berechnung in die CRC 
Variable schreibt. Üblicherweise ist das meist 0x00 oder 0xff...

2.Methode (nondirect)
Initialisiert man die CRC-Variable mit 0x00 und schreibt dafür 0xff an 
den Anfang des Datenframes, dann startet man quasi mit der CRC von 0xff 
nach der 1.Methode.

Es gilt halt was Jörg schon ausgeführt hat

Jörg Wunsch schrieb:
> Das ist eigentliche Problem mit den CRCs, man muss nicht nur den
> Startwert und das Generatorpolynom kennen, sondern auch noch die
> Bitreihenfolge.  Sinnvollerweise sollte man also bei jedem praktisch
> beschriebenen Algorithmus auch gleich noch eine Beispielsequenz
> dabei stehen haben.

Die Regel ist einfach die: Man benutze den gleichen Algorithmus wie die 
Gegenstelle !!!
Gast #2218605
Lesenswert?

Hallo,

sehe ich genauso mit der Gegenstelle.
Hatte auch das Problem, habe aber dann einfach die ganze Bitdreherei 
gelassen. So lange dies nicht verlangt ist nach einem Standard macht man 
es einfach so, wichtig ist nur dabei das Sende und Empfangsstation es 
gleich machen.


Gruß
paule
Gast #2356144
Lesenswert?

Hallo,

ich habe ein ähnliches Problem.

Es geht um eine CRC8 mit folgenden Parametern
x8+x5+x3+x2+x1+x0 (i.e. 0x2F with the leading one omitted)
The initial start value is 0xFF while the target value is 0x00.

Ich benutze folgenden Code:
1
// Polynom 0x2F
2
// start wert 0xFF
3
// Target 0x00 
4
__int8 crc8__update( __int8 crc, __int8 data)
5
{
6
  __int8 i;
7

8
  crc = crc ^ data;
9
    for (i = 0; i < 8; i++)
10
    {
11
        if (crc & 0x80)
12
            crc = (crc << 1) ^ 0x2F;//0x1D;//0x8C;
13
        else
14
            crc <<= 1;
15
    }
16

17
  return crc;
18
}
19

20
...
21

22
  unsigned __int8 buffer[]={ 0x40,0x2B,0x03 }; //B6 CRC
23
  unsigned __int8 crc;
24

25
  crc=0xFF;
26
  for( unsigned __int8 i = 0 ; i < sizeof(buffer) ; i++ )
27
  {
28
    crc=crc8__update( crc, buffer[i] );
29
  }
30
  printf( ":%02X", crc );
31
  printf( ":%02X", crc^0x00 );
32
  printf( ":%02X", crc^0xFF );

Richtig gerechnete Beispiele von Strings mit CRC8:
0x402901 15
0x402B83 55

Vielleicht sieht ja jemand meine Fehler ?
Was bedeutet Target 0x00 ?

Gruß
Jörg
Moderator Persönliche Seite #2356371
Lesenswert?

Jörg Stamm schrieb:

> ich habe ein ähnliches Problem.

Auch wenn das Problem ähnlich scheint: oft ist es am Ende doch was
anderes => eigenen Thread aufmachen.

>   __int8 i;

Lass dich nicht mit __int8 erwischen.  Bezeichner mit zwei führenden
Unterstrichen sind `reserved for the implementation'.  Und die
`implementation' stellt dir gemäß dem aktuellen C-Standard über
den Header <stdint.h> den Datentyp int8_t bereit (wobei ich mich
gerade frage, ob du nicht eher uint8_t nehmen willst).

> Vielleicht sieht ja jemand meine Fehler ?

Wenn du uns verrätst, was für dich denn der Fehler ist?

> Was bedeutet Target 0x00 ?

Dass nach dem vollständigen Algorithmus über Datenstrom + CRC eine
0 rauskommen soll.  Das ist aber normal.
Gast #2356741
Lesenswert?

Hey,

der Fehler ist, daß die CRC nicht richtig ausgerechneet wird.

Auch wenn ich die CRC mit in die Berechnung einfließen lasse, komme ich 
nicht auf 0x00.

Ich habe zu Testzwecken die Routine in VC++ getestet, da muß man doch 
__int8 für eine 8bit Integer benutzen ? Nicht das da mein Fehler liegt.

Gruß
Jörg
Moderator Persönliche Seite #2356822
Lesenswert?

Jörg Stamm schrieb:
> der Fehler ist, daß die CRC nicht richtig ausgerechneet wird.

Dann mach' bitte dein Beispiel verständlicher, oder schreib' uns,
wofür die CRC da gut ist.  Irgendjemand wird ja die "Gegenstelle"
sein, der das so festgelegt hat.  Vielleicht ist dessen Beschreibung
ja verständlicher als dein Text.

> Ich habe zu Testzwecken die Routine in VC++ getestet, da muß man doch
> __int8 für eine 8bit Integer benutzen ?

Keine Ahnung, kenne ich nicht.
Gast #3173331
Lesenswert?

Hi,

habe gesehen ihr habt euch über das Thema CRC anch SAE J1850 berechnen 
schon ordentlich ausgetauscht. Ich brauche auch einen C-Code, um eine 
CRC-Prüfsumme gemäß SAE J1850 folgender Botschaft zu berechnen:

C7 40 0C 00 00 00 00

Laut Vorgabe des Autors dieser CAN-Botschaft soll für die CRC-Prüfsumme 
der Wert 53(hex) rauskommen. Da ich noch recht wenig Erfahrung in C und 
auch sonst KEINERLEI Erfahrung mit Embedded Systems o.ä. habe, wäre ich 
über einen einfachen C-Code für mein Problem sehr dankbar. Ihr habt oben 
bereits zum Beitrag von Jörg geschrieben, was man abändern muss, aber so 
ganz klar war mir das leider nicht. Kann mir bitte jemand einen 
vollständigen C-Code posten?

Vielen Dank für jede Antwort,

Joe
Gast #3173342
Lesenswert?

Joe schrieb:
> Kann mir bitte jemand einen
> vollständigen C-Code posten?

Aber gerne:
1
 crc = 0x53;

Aller weitere steht in den Beiträgen weiter oben. Wenn dier da snicht 
ausreicht, wirst du den Umweg über "Ich lerne richtig C, von Anfang an" 
nehmen müssen.

Oliver
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.