Forum: Mikrocontroller und Digitale Elektronik CRC Berechnung mit LUT


von Gee (Gast)


Lesenswert?

Ich möchte eine CRC16 mithilfe einer LUT berechnen.

Die CRC von nur einem Byte ist einfach. Für das Byte 0xFF schaue ich 
einfach im 256. Eintrag der LUT das wäre dann CRC 0x1EF0

So wenn ich jetzt aber 2x 0xFF sende und davon die CRC haben möchte wie 
komme ich jetzt darauf ? Der richtige Wert währe hier 0x1D0F

Ich finde hier einfach keinen Weg wie ich da weiterrechne..

von Chris (Gast)


Lesenswert?

Wenn du vorher in lut 255 nachgeschaut hast, dann schau jetzt einfach in 
lut 225 nach und XOR das Ergebnis mit f0.

CRC = lut[(CRC >> 8) ^ val]^crc<<8

von Gee (Gast)


Lesenswert?

wie kommst du auf den index 225 ? Ich sende in meinem Beispiel ja 2x FF 
also müsste ich doch 2x im index 255 nachschauen oder ?

von Jobst M. (jobstens-de)


Lesenswert?

Gee schrieb:
> So wenn ich jetzt aber 2x 0xFF sende und davon die CRC haben möchte wie
> komme ich jetzt darauf ? Der richtige Wert währe hier 0x1D0F

Konsequenterweise schaust Du in einer 64k*16 Tabelle nach ...

Gruß
Jobst

von Falk B. (falk)


Lesenswert?

Jobst M. schrieb:
>> So wenn ich jetzt aber 2x 0xFF sende und davon die CRC haben möchte wie
>> komme ich jetzt darauf ? Der richtige Wert währe hier 0x1D0F
>
> Konsequenterweise schaust Du in einer 64k*16 Tabelle nach ...

Nö. Man schau 2 mal in einer 256x16 Tabelle nach und macht zwischen 
durch die passende XOR-Verknüpfung. Siehe CRC.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Kleine Feierabendlektuere, vielleicht insbesondere Kap.9:
https://zlib.net/crc_v3.txt

Gruss
WK

von Gee (Gast)


Lesenswert?

Was genau soll ich da Xoren ?

Die CRC von 1x FF = 0x1EF0  1111011110000
und von 2xFF = 0x1D0F      1110100001111


wie komme ich auf die zweite crc?

von Gee (Gast)


Lesenswert?

Wenn ich die vorherige CRC mit dem nächsten Byte ver-x-odere kommt 
1111000001111 raus. Was aber falsch ist. Es sollte 1110100001111 
rauskommen..

was mache ich falsch ??

von Chris (Gast)


Lesenswert?

Gee schrieb:
> Was genau soll ich da Xoren ?
>
> Die CRC von 1x FF = 0x1EF0  1111011110000
> und von 2xFF = 0x1D0F      1110100001111
>
>
> wie komme ich auf die zweite crc?

Chris schrieb:
> CRC = lut[(CRC >> 8) ^ val]^crc<<8

Also lookup(225) = 0xED0F , dies mit 0xf000 xor-en -> 1d0f

von PittyJ (Gast)


Lesenswert?

Habt ihr kein Google?

Unter den ersten Ergebnissen wird das gezeigt:
https://stackoverflow.com/questions/22432066/how-to-use-table-based-crc-16-code

von Gee (Gast)


Lesenswert?

Chris schrieb:
> dies mit 0xf000 xor-en

Das Ergebniss, stimmt aber kannst du mir erklären wie du auf F000 kommst 
?

von Gee (Gast)


Lesenswert?

Chris schrieb:
> CRC = lut[(CRC >> 8) ^ val]^crc<<8

Mein Problem ist ich verstehe diese Zeile nicht.. arbeite ausschließlich 
mit Assembler. Soll ich CRC 8x nach rechts shiften und dann mit dem 2. 
Byte ver-x-oren?

von Gee (Gast)


Lesenswert?

glaube ich habs, vielen Dank erstmal

von Gee (Gast)


Lesenswert?

mit 2x 0xFF funktionierts, aber mit 0x31 0x32 nicht... wo liegt der 
Fehler? Muss ich am Ende immer mit 0xF000 maskieren?

von Falk B. (falk)


Lesenswert?

Gee schrieb:
> mit 2x 0xFF funktionierts, aber mit 0x31 0x32 nicht... wo liegt der
> Fehler? Muss ich am Ende immer mit 0xF000 maskieren?

Am Ende wird gar nix maskiert. Bestenfalls wird die CRC mit einem Wert 
ungleich 0x00 initialisiert. Das hängt aber von der Anwendung ab. Ich 
wiederhole mich. Siehe CRC bzw. der Klassiker.

http://www.ross.net/crc/download/crc_v3.txt

Eine praktische Anwendung einer 8 Bit CRC in Assembler gibt es u.a. hier

Beitrag "Re: Onewire + DS18x20 Library"

von Chris (Gast)


Lesenswert?

CRC = lut[(CRC >> 8) ^ val]^crc<<8
CRC = 0x5e36 byte=0x20
High byte von CRC XOR byte
0x5e XOR 0x20 = 0x7e = 126 DEC
Lut 126 = 0x23f5 Fantasiewert
Low byte vom alten CRC 8x links shiften und XOR
Also 0x23f5 XOR 0x3600 = 0x15f5

von Gee (Gast)


Lesenswert?

habe das 8x nach links shiften oben bei den 2x FF vergessen und das 
Ergebniss hat zufällig trotzdem gestimmt. Versuche jetzt das 
linksshiften mit einzubauen, aber mir raucht gerade der Kopf vom ganzen 
umrechnen und 0 und 1 en geschubse. Mach kurz pause und setz mich dann 
nochmal ran vielen Dank für eure Gedult ^^

von Tippgeber (Gast)


Lesenswert?

Du sollst das High-Byte mit dem val (0xFF) xoren, in der LUT nachschauen 
und das High-Byte des Tabellenzugriffs mit dem Low-Byte xoren.

CRC ist in C was anderes als crc (case sensitiv).

Shiften braucht man hier gar nicht. Das schreibt man in C, um auf das 
Low- oder Highbyte zugreifen zu können.
Zeig mal deinen Code und die Parameter (Startwert (Seed), Polynom, 
Tabelle etc.)
Ich denke, du machst es dir zu kompliziert. Lookup-CRC sind nur ein paar 
(5?) Befehle.

Falls danach z.B. nochmal invertiert oder geschoben wird, hat das den 
Grund, dass offensichtliche Übertragungsfehler (0x00 oder 0xFF) erkannt 
werden, was bei reiner CRC nicht möglich wäre.

von Gee (Gast)


Lesenswert?

Chris schrieb:
> CRC = lut[(CRC >> 8) ^ val]^crc<<8
> CRC = 0x5e36 byte=0x20
> High byte von CRC XOR byte
> 0x5e XOR 0x20 = 0x7e = 126 DEC
> Lut 126 = 0x23f5 Fantasiewert
> Low byte vom alten CRC 8x links shiften und XOR
> Also 0x23f5 XOR 0x3600 = 0x15f5

Yess. Macht Sinn und funktioniert. Vielen Dank an alle. Bin bei neuen 
Sachen immer schwer von Begriff

von Gee (Gast)


Lesenswert?

Hier meine funktionierende routine

jetzt muss ich das ganze noch für CRC7 machen
1
calc_CRC_16:
2
    mov      CRC_16,W0      // crc in High und Low Byte unterteilen
3
    mov      W0,WORD
4
    call    SPLIT
5
       
6
    mov      DATA,W0
7
    xor      H_BYTE      // xor mit neuem Byte
8
        
9
    mov      #0,W0
10
    mov      W0,TBLPAG
11
        
12
    mov      #2,W0
13
    MUL      H_BYTE          
14
          
15
    mov      W2,TBL_INDEX
16
    
17
    mov      #0x7850,W0
18
    add      TBL_INDEX      
19
    
20
    MOV      TBL_INDEX,W0 
21
    
22
    TBLRDL  [W0],W4     
23
    mov      W4,CRC_16      // CRC aus Tabelle lesen 
24
    
25
    repeat  #8-1
26
    rlnc    L_BYTE  // altes Low CRC nach links shiften    
27
    
28
    mov      L_BYTE,W0
29
    xor      CRC_16
30
    
31
    return

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.