Hallo lezers van het CO Forum

Na een tijdje gezocht te hebben naar informatie over CRC heb ik een beetje een idee wat het is. Maar nog niet helemaal en dat om ben ik hier.

Maar laat ik eerst eens zeggen waarvoor ik het nodig heb.
Ik probeer een Crystalfontz display, de CFA635, te Emuleeren(Na apen) met een ATMega32 , een 4*20 lcd'tje en een MAX232.

Dit CFA635 display stuurt en ontvangt pakketjes met een CRC16 controle er bij. Maar hoe kan ik zelf een CRC controlle uit voeren in BasCom.
Ik zag dat er in BasCom een CRC16 comando is maar met welk getal hij dit doet.

Welk getal ik nodig heb is X^16 + X^12 + X^5 + X^0 = 0x8408

Hier nog even de link naar de datasheet van CFA635.
http://www.crystalfontz.com/products/635/data_sheets/CFA635-TMF_v1.4c.…

Ik hoop dat ik helder ben geweest.

Alvast bedankt,
Oscar

Ik weet niet of je hier wat aan hebt, het is in assembly. Ooit eens CRC bereken routines gemaakt. Standaard methode met bitshiften, snelle methode met lookup. 1x lookup tabel genereren op basis van je gewenste polynoom, dan CRC'en maar.

Overigens, de polynoom die je opgeeft is 4129 decimaal.


;   =================================================================================================
;	Definitions
;   =================================================================================================

    				.include "m128def.inc"

                    .equ XX             = 0

;   =================================================================================================
;	RAM variabeles
;   =================================================================================================

                    .dseg

                    .org SRAM_START

CRCLookup:          .byte 512
DataStream:         .byte 1024

;   =================================================================================================
;	Interrupt vector table
;   =================================================================================================

    				.cseg

    				.org 0x0000
                    RJMP PrgInit                        ;Reset vector

;   =================================================================================================
;	Program
;   =================================================================================================

				    .org INT_VECTORS_SIZE               ;Start of application area

PrgInit:            ;** Setup stack
                    LDI R16, Low(RAMEND)                ;Initialize the stack pointer
    				OUT SPL, R16
                    LDI R16, High(RAMEND)
    				OUT SPH, R16
                    ;** Copy 200 bytes data from ROM to RAM and terminate with 2x 0x00
                    LDI R24, 200
                    RCALL PrgInitRAM
                    ;** Generate some CRC with ole bitshifting
                    LDI XL, Low(DataStream)
                    LDI XH, High(DataStream)
                    LDI R24, 202
                    LDI R23, 0x10
                    LDI R22, 0x21
                    RCALL PrgCRC
                    ;** Generate lookup for polynomian
                    LDI XL, Low(CRCLookup)
                    LDI XH, High(CRCLookup)
                    LDI R23, 0x10
                    LDI R22, 0x21
                    RCALL PrgLookup
                    ;** Generate some CRC using lookup
                    LDI XL, Low(DataStream)
                    LDI XH, High(DataStream)
                    LDI R24, 202
                    RCALL PrgCRCLUT


PrgEnd:             RJMP PrgEnd

                    ;** Input
                    ;
                    ; XH:XL     RAM Pointer
                    ; R24       Byte Count
                    ;
                    ;** Output
                    ;
                    ; R21       CRC High
                    ; R20       CRC Low
                    ;
                    ;** Modifies
                    ; ZH:ZL     Lookup address
                    ; R25       0
                    ; R19       Feeder
PrgCRCLUT:          CLR R25
                    LDI R21, 0xFF
                    LDI R20, 0xFF

PrgCRCLUTLoop:      LD R19, X+

                    LDI ZH, High(CRCLookup)
                    MOV ZL, R21
                    LSL ZL
                    ADC ZH, R25

                    LD R21, Z+
                    EOR R21, R20
                    LD R20, Z+
                    EOR R20, R19

                    DEC R24
                    BRNE PrgCRCLUTLoop
                     
                    SBIW XH:XL, 0x0002
                    ST X+, R21
                    ST X+, R20
                    RET

                    ;** Input
                    ;
                    ; XH:XL     RAM Pointer
                    ; R23       Poly High
                    ; R22       Poly Low
                    ;
                    ;** Modifies
                    ;
                    ; R25       Bit Counter
                    ; R24       Byte Counter
                    ; R21       Intermediate
                    ; R20       Intermediate
                    ; R19       Intermediate
                    ; R18       Intermediate
                    ; R16       Intermediate
PrgLookup:          LDI R24, 0

PrgLookupByte:      LDI R25, 8
                    MOV R20, R24
                    CLR R19
                    CLR R18

PrgLookupBit:       LSL R19
                    ROL R18
                    LSL R20
                    BRCC PrgLookupNoXor

                    EOR R20, R23
                    EOR R19, R23
                    EOR R18, R22

PrgLookupNoXor:     DEC R25
                    BRNE PrgLookupBit

                    ST X+, R19
                    ST X+, R18

                    INC R24
                    BRNE PrgLookupByte

                    RET

                    ;** Input
                    ;
                    ; XH:XL     RAM Pointer
                    ; R24       Byte Count
                    ; R23       Poly High
                    ; R22       Poly Low
                    ;
                    ;** Output
                    ;
                    ; R21       CRC High
                    ; R20       CRC Low
                    ;
                    ;** Modifies
                    ; R25       Bit counter
                    ; R19       Feeder
PrgCRC:             LDI R21, 0xFF
                    LDI R20, 0xFF
PrgCRCByteLoop:     LD R19, X+
                    LDI R25, 8
PrgCRCBitLoop:      LSL R19
                    ROL R20
                    ROL R21
                    BRCC PrgCRCNoXor
                    EOR R21, R23
                    EOR R20, R22
PrgCRCNoXor:        DEC R25
                    BRNE PrgCRCBitLoop
                    DEC R24
                    BRNE PrgCRCByteLoop
                    SBIW XH:XL, 0x0002
                    ST X+, R21
                    ST X+, R20
                    RET

PrgInitRAM:         LDI ZL, 0x00
                    LDI ZH, 0x00
                    LDI XL, Low(DataStream)
                    LDI XH, High(DataStream)
PrgInitRAMLoop:     LPM R16, Z+
                    ST X+, R16
                    DEC R24                    
                    BRNE PrgInitRAMLoop
                    LDI R16, 0
                    ST X+,R16
                    ST X+,R16
                    RET

MagicBox bedankt voor de snelle reactie maar ik denk niet dat ik veel aan je code heb, ik progerameer in BasCom. Maar bedankt.

Maar je zou me er erg helpen om deze routine in pseudocode uit te legen of een mischien heb je een goed link (liefst Nederlands) waar goede/duidelijke uitleg staat.

En 0x8408 heb ik direct uit de datasheet getrokken. Maar ik denk dat ze de het in Hex bedoelen.

Groet,
Oscar

Ik heb geen idee van BasCom, ik zou geen vertaling voor je kunnen maken. Het is allemaal bitshift werk wat er moet gebeuren. Het beste zou zijn om een software uitvoering van een hardware matige CRC te maken. Googlen op 'CRC circuit' en je vind ze wel.

Waar je op moet letten is om je reeks bytes af te sluiten met 2x 00h als je gaat genereren. Als je over 100 bytes CRC wil maken, dan je routine over 102 bytes laten gaan waarbij de laatste 2 00h zijn die je er zelf aanplakt.

Die laatste 2 dan vervangen met de gegenereerde code en dat clubje versturen. De ontvanger zal over die reeks van 102 bytes dezelfde routine uitvoeren. De uitkomst zal aan zijn kant weer 2x 00h moeten zijn. Zijn ze dat niet, was er iets fout gegaan tijdens het versturen. Dat is het principe.

Even gezocht voor je op het bascom forum;

Bascom uses &H1021 (dec 4129) as the polynome for it's CRC16 function

Is dat wat je bedoelde?

Dat is de goeie ja. de x16+x12+x5+x0 is de standaard voor telecommunicatie, wordt ook wel CCITT genoemd. Lijkt er op dat je gewoon die BasCom functie gebruiken kan dan.

met deze code bereken je enventueel aan de andere kant (PC) je CRC16 gelijk aan die van Bascom:
misschien heb je daar ook wat aan in latere projectjes die met de PC moeten communiceren, het is in Delphi maar de basis moet wel duidelijk zijn voor iedere andere taal...


procedure DoCRC16(X: Byte); 
var
  I : Byte;
  F : Boolean;
begin
  for I := 1 to 8 do begin
    F := Odd(X xor CRC16);
    CRC16 := CRC16 shr 1;
    X := X shr 1;
    if F then
      CRC16 := CRC16 xor $A001;
  end;
end;

en dat is in C++ voor CRC8 van Bascom:


unsigned char Data[9];

Data = {D1,D2,D3,D4,D5,D6,D7,D8,D9};

BYTE j,k,m,x;
BYTE _crc8;

_crc8 = 0;
for(m=1;m<=9;m++)
{
    x = Data[m];
    for(k=0;k<=7;k++)
    {
        j = 1 & (x ^ _crc8);
        _crc8 = (_crc8 >> 1) & 0xff;

        x = (x >> 1) & 0xff;
        if (j != 0)
        {
            _crc8 = _crc8 ^ 0x8C;
        }
    }
}
crc = _crc8;
}

[Bericht gewijzigd door shortcircuit op (30%)]

Ja BasCom gebruikt inderdaad 4129 als polynoom. Ik heb dat ff gecheckt met deze site. http://www.lammertbies.nl/comm/info/nl_crc-calculation.html?crc=0100&a…)

Maar het debug programma van de Crystalfontz web site geeft Hex169F als CRC over Hex0100 terwijl dit met BasCom en via die site Hex3331 moet zijn.

Hier kan je het debug programma downloaden om het met eigen ogen te zien.
http://www.crystalfontz.com/software/635_WinTest/index.html

Maar ik krijg het idee dat die debug software nog iest anders doet dan allen CRC16.
Dit staat in de datasheet:
"The polynomial used is X16 + X12 + X5 + X0 (0x8408)
The result is bit-wise inverted before being returned."
Maar wat bedoelen ze met bit-wise inverted?

Iedereen bedankt, ik snap nu wel wat CRC is en hoe het werkt,maar nog niet hoe dat display het gebruikt.

Groet,
Oscar

lol ik zie het nu

0x1021 is 0x8408 achterstevoren

0001 0000 0010 0001 = 0x1021

1000 0100 0000 1000 = 0x8408

De reeks wordt gewoon omgedraaid.

Ow oke.

1 0000 1000 0001 0001
Is de Polynoom voor crc-CCITT volgens mij.

Maar wat is dat Bit-wise inverted dan?
Of is dat wat jij bedoelt MagicBox?

Groet,
Oscar

Dat is wat ik bedoelde ja.. die term is een beetje klungelig gekozen van ze daar bitwise inverteren een xor met allemaal 1'en is. 1'tjes worden 0, 0'en worden 1.

Oke dat snap nu.
Maar hoe kommen ze dan aan 169F als ze CRC16 over hex0100 uit voeren. Mischien heb je het Debug programma gedownload. Want daar kan je bij pakket debugger zien hoe de pakketjes zijn op gebouwd en welke crc word mee gestuurt.

De pakketjes zijn zo opgebouwt:
<type><data_length><data><CRC>
Waar type = hex01
Waar data_length = hex00
Waar data = niks en word dus ook niet verstuurt

Dus de string waar de crc over gaat is hex0100 en zou hex3331 als CRC terug moeten geven, maar de software van Crystalfontz geeft hex169F als CRC terug.

Gebruiken ze toch een ander polynoom of doen ze eerst nog wat met de data string voordat ze CRC'en of zie ik wat over het hoofd?

Groet,
Oscar