Forum: Mikrocontroller und Digitale Elektronik PIC PIC12 PIC16 CRC16 CCITT Berechnung in Assembler


von Stefan (Gast)


Lesenswert?

Hallo,
auch nach langer Suche im Internet, bin ich nicht auf einen
schnellen, richtig rechnenden und verständlichen Quellecode
zur Berechnung einer CRC16 Prüfsumme in Assembler für kleine PICs 
gestoßen.
Nach dem Studium eines Artikels zur CRC16 Berechnung mit PIC18xxx
bin ich auf die Lösung gekommen und möchte diese hier einfach einmal
verewigen.

benötigte Variablen:
-------------------
1
       CBLOCK  0x20; RAM Bereich startet ab Adr 0x20
2
CRC16L ; die berechnete Prüfsumme
3
CRC16H
4
TEMP   ; Hilfsvariable
5
CTR    ; Zähler für Schleifendurchläufe
6
       ENDC  ; Ende der Variablendefinition
die Initialisierung:
1
        movlw  0xFF
2
        movwf  CRC16L ; CRC16 mit dem Startwert xFFFF initialisieren
3
        movwf  CRC16H ; ein anderer Startwert ist möglich
Benutzung:
Es werden der Reihe nach alle Datenbytes ins W Register kopiert
und jeweils die Berechnungsroutine aufgerufen mit:
1
        call   CALC_CRC16

Das Programm:
1
#define POLYNOM  0x1021 ; hier das Generatorpolynom eintragen
2
3
CALC_CRC16:
4
        movwf   TEMP ; übergebenes Datenbyte sichern
5
        movlw   8
6
        movwf   CTR
7
CRC16_LOOP:
8
        rlf     TEMP,F ; CRC16 += 1, wenn MSB=1
9
        ; CRC16 schieben
10
        rlf     CRC16L,F
11
        rlf     CRC16H,F
12
        ; MSB=1?
13
        btfss  STATUS,C
14
        goto  CRC16_1
15
        ; XOR mit Generatorpolynom
16
        movlw  LOW POLYNOM ; 0x21
17
        xorwf   CRC16L,F
18
        movlw   HIGH POLYNOM ; 0x10
19
        xorwf   CRC16H,F
20
        ;
21
CRC16_1:decfsz  CTR,F ; schon alle 8 Bits des Bytes aus W verarbeitet
22
        goto  CRC16_LOOP
23
        RETURN

Nach dem die Prüfsumme für alle Bytes berechnet wurde,
steht das Ergebnis in der Variable CRC16H,CRC16L bereit.
Der Code ist getestet.

Grüße
Stefan

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Man kann so etwas mithilfe von Look-Up-Tables noch stark beschleunigen - 
mit einer cleveren Konstruktion geht das auch bei einer CRC-16 ohne eine 
2^16 große Tabelle. Der Verständlichkeit ist das aber nicht so 
zuträglich :-)

http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html

von Thomas E. (picalic)


Lesenswert?

Niklas G. schrieb:
> Man kann so etwas mithilfe von Look-Up-Tables noch stark beschleunigen

Kann man machen, wenn man es wirklich schneller braucht. Gerade bei den 
kleinen PICs ist es aber meistens eher der Speicherplatz, um den man 
sich Sorgen macht. Und wenn beides nicht zu knapp ist, ist ein 
übersichtlicher Algorithmus auch vorteilhaft.
Die Low- und Midrange PICs sind auch nicht gerade ein Musterbeispiel an 
Effizienz bei der Implementation von Lookup-Tabellen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Thomas E. schrieb:
> Kann man machen, wenn man es wirklich schneller braucht.

Stefan schrieb:
> schnellen

Es war gefordert :-)

Thomas E. schrieb:
> Gerade bei den
> kleinen PICs ist es aber meistens eher der Speicherplatz, um den man
> sich Sorgen macht. Und wenn beides nicht zu knapp ist, ist ein
> übersichtlicher Algorithmus auch vorteilhaft.
> Die Low- und Midrange PICs sind auch nicht gerade ein Musterbeispiel an
> Effizienz bei der Implementation von Lookup-Tabellen.
Okay, das war mir nicht bewusst. Eine solche LUT wäre typischerweise 256 
Byte groß und würde den Code ca 8x beschleunigen, ist das schon zu viel?

von Peter D. (peda)


Lesenswert?

Niklas G. schrieb:
> Eine solche LUT wäre typischerweise 256
> Byte groß und würde den Code ca 8x beschleunigen, ist das schon zu viel?

Bei einem PIC12 mit 1kWords Flasch sind das schonmal 25% mit RETLW 
verballert. Und dabei auch noch das Überschreiten der Pagegrenzen 
beachten.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Bei einem PIC12 mit 1kWords Flasch sind das schonmal 25% mit RETLW
> verballert.
Oh, hat der kein LPM-Äquivalent? Das ist ja schlimm :-)

Man könnte auch eine 4-Bit-LUT nehmen o.ä., man müsste eine 
Versuchsreihe machen ob sich das lohnt.

Auf größeren Controllern wie Cortex-M ist die LUT ziemlich sinnvoll, da 
auch diese Controller solche Bitschnipseleien nicht wirklich besser 
können, und Flash meist genug da ist. Aber ok, darum ging's nicht

von P.Loetmichel (Gast)


Lesenswert?

Bascom hätte gleich eine CRC8, CRC16 oder CRC32 mitgebracht.

Profis nehmen Bascom und sind schneller fertig.

von Gee (Gast)


Lesenswert?

dsPIC33 nehmen und gut ist. Ich fass diesen 8 Bit Mist seit 10 Jahren 
nicht mehr an.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefan schrieb:
> bin ich auf die Lösung gekommen und möchte diese hier einfach einmal
> verewigen.

Danke, kann immer mal nützlich sein!

Stefan schrieb:
> Nach dem Studium eines Artikels zur CRC16 Berechnung mit PIC18xxx

Wäre auch interessant zu lesen.


@Moderator, bitte verschieben zu Projekte&Code, damit der Code nicht im 
Nirvana verbleibt.

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.