CRC16 (aus lib)

Begonnen von Geni, 23. November 2010, 17:10:08

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 1 Gast betrachten dieses Thema.

Geni

Hallo,

ich soll eine Schnittstelle über eine Wago 750-841 zu einer Grunfos Pumpe in Codesys erstellen.
Dieses Protokoll verlangt eine CRC-Berechnung. Die CRC-Prüfsumme wird nach CRC16-CCIT mit dem Polynom 0x1021 gebildet.
Hier ist der der Code den ich Sende:
PROGRAM PLC_PRG
VAR
wBaudRate: WORD := 960;
bDataBits: BYTE := 8;
bParity: BYTE := 0;
bFlowControl: BYTE := 4;
i: INT;

COM2: SERIAL_INTERFACE;
xOpenPort2: BOOL := TRUE;
xInitPort2: BOOL;
xSendActive2: BOOL;
ReceiveBuffer2: typRing_Buffer;
bySend:ARRAY [0..255] OF BYTE;
byReceive:ARRAY [0..255] OF BYTE;

CRC_OK: BOOL; (*CRC i.o.*)
Length: BYTE;


[b](* Send and Receive for COM2 *)[/b]
COM2( bCOM_PORT_NR := 2,
cbBAUDRATE := wBaudRate,
cbsBYTESIZE := bDataBits,
cpPARITY := bParity,
csSTOPBITS := STOPBITS_1,
cfFLOW_CONTROL := bFlowControl,
iBYTES_TO_SEND :=18,
ptSEND_BUFFER :=ADR(bySend),
utRECEIVE_BUFFER := ReceiveBuffer2,
xINIT := xInitPort2,
      xOPEN_COM_PORT := xOpenPort2,
xSTART_SEND := xSendActive2 );

(* Request data for COM2 *)
bySend[0]:=cDataRequest;
bySend[1]:=16#0E ;
bySend[2]:=16#FE;
bySend[3]:=16#01;

bySend[4]:=cClass0;
bySend[5]:=16#02;
bySend[6]:=16#02;
bySend[7]:=16#03;
bySend[8]:=cClass4;
bySend[9]:=16#02;
bySend[10]:=16#2E;
bySend[11]:=16#2F;
bySend[12]:=cClass2;
bySend[13]:=16#02;
bySend[14]:=16#94;
bySend[15]:=16#95;

bySend[16]:=16#A2;
bySend[17]:=16#AA;


(* Data for COM2 *)
IF (ReceiveBuffer2.Index > 0) AND (ReceiveBuffer2.Data[0]=16#24) AND ((ReceiveBuffer2.Index-4) = ReceiveBuffer2.Data[1]) THEN
IF (ReceiveBuffer2.Data[0] <> 16#26) THEN
IF (ReceiveBuffer2.Data[0] <> 16#27) THEN
IF (ReceiveBuffer2.Data[2] = 16#01) THEN

(*CRC-Programm*)
Length := ReceiveBuffer2.Data[1];
CRC_OK := CRC_CHECK(ADR(ReceiveBuffer2.Data[1]),Length,696650,FALSE); (*Length = 10*)

FOR i :=0 TO ReceiveBuffer2.Index BY 1 DO
byReceive[i]:=ReceiveBuffer2.Data[i];
END_FOR
ReceiveBuffer2.Index := 0;
END_IF
END_IF
END_IF
END_IF



und das bekomme ich zurück:

16#24,16#0A,16#01,16#23,16#04,16#02,16#23, 16#E7;16#00;16#02;16#64;16#0E;16#48;16#94  (*Orginal Reply von einer Pumpe*)
                                          
die Werte die ich hier bekomme sind absolut plausibel, die Checksumme ist dann das Fett gedruckte.


Die Frage ist jetzt wie muß ich das in CRC_GEN übertragen damit der den CRC_CHECK dann ausführt?
Kann mir jemand einen Tipp geben?

Vielen Dank für Eure Hilfe

Geni

Hi ich hab noch mal ein paar Stunden dran weiter gearbeitet aber auch noch nicht weiter gekommen.
Deswegen hab ich hier mal meine Datei angehängt.
Vielleicht kann mal jemand nach schauen.

Gruß Dom

[gelöscht durch Administrator]

Geni

Hi Leute,
ich hab mal versucht nur die Checksumme zu generieren, mit dem CRC_GEN, und komm am Ende auf ein falsches CRC Ergebnis (4CBB).
Was mach ich Falsch mein CRC müsste meiner Meinung nach 4894 sein. (CRC-CCITT, 16#1021 (x16+x12+x5+1) bezogen auf ein GENIbus-Protokoll)
24,0a,01,23,04,02,23,f7,00,02,64,0e,48,94 = CRC

Hier mal mein Reply nach dem Request:

[00] 16#24 = Reply (Start Delimiter)
[01] 16#0A = Length (=10)
[02] 16#01 = Ziel Adresse
[03] 16#23 = Quell Adresse
[04] 16#04 = Class4 (Config Para)
[05] 16#02 = Length von Class4
[06] 16#23 = unit addre.
[07] 16#F7 = group addre.
[08] 16#00 = Class0 (Protocol Data)
[09] 16#02 = Length von Class0
[10] 16#64 = df buf len
[11] 16#0E = unit bus mode
[12] 16#48 = crc high
[13] 16#94 = crc low

Laut der Beschreibung des Herstellers zählt alles mit rein außer das Start Delimiter.
Hab es auch schon ohne Start Delimiter und ohne CRC versucht komme einfach nicht auf die 4894.
Bin echt so langsam am verzweifeln kann mir den da niemand weiter helfen. ???


[gelöscht durch Administrator]

Geni

Hat sich erledigt hab selber ein CRC geschrieben

hugo

deine hex messase in einen CRC Rechner im Internet eingegegben ergibt das ergebnis 84e9 ! und nicht 4894

http://zorc.breitbandkatze.de/crc.html
dies ist quasi die referenzseite für die meisten CRC publikationen im internet.

die problematik dürfte aber am polynom liegen. CRC-CCITT mit polynom 1021 sagt noch lange nicht alles über die CRC berechnung aus.
wichtig sind startwert, (direkt oder indirekt), byteorder, msb oder lsb first, final XOR und auch noch die CRC bitfolge.
all dies muss richtig spezifiziert sein um zum richtigen ergebnis zu kommen.
Zu allem überdruss ist es üblich in der literatur das oberste bit vom polynom wie z.b. beim $1021 zu verschweigen. das 16. bit wird hier im polynom nicht angegeben weil es ja zwingend immer eins sein muss.
leider benötigte der OSCAT Baustein dieses Bit in der Angabe, das ist auch so im Manual dokumentiert.

wir haben nun mehrere Tage mit den CRC gearbeitet und dabei einen ganz neuen baustein geschrieben der hoffentlich auch besser handhabbar sein wird und nebenbei schneller rechnet als der alte.
nichts desto trotz wird immer die genaue recherche über die richtigen parameter des CRC nötig sein, in unserem manual findet sich eine beachtliche liste mit crc parametern die aber nur ein kleiner auszug aus den zahllosen verbreiteten CRC's ist.

zudem war unser alter baustein bei manchen polynomen fehlerhaft.
wir hoffen das der neue baustein nach tagelangen tests mit zahlreichen polynomen und einstellungen sicher funktioniert.

unser neuer baustein liefert das richtige ergebnis $4894 mit folgenden parametern:

Polynom 1021, Startwert 84CF nondirect (direct = FFFF) final XOR FFFF REV_IN und REV_OUT = False
der erste Wert $24 darf nicht nmit eingerechnet werden.

ein hinweis zu startwert: wir benutzen den startwert nondirect, es sind sowohl direct alks auch nondirect gebräuchlich, und beide können umgerechnet werden.
um jedoch rechenzeit im baustein zu sparen haben wir uns für nondirect entschieden.

siehe hierzu auch: http://www.lammertbies.nl/forum/viewtopic.php?t=216
gute informationen zu CRC finden sich auf der englischen wickipedia. die ist deutlich ausführlicher als die deutsche, zusätzlich gibt es in der englischen wicki auch noch eine umfangreiche seit über algorithmen und berechnungen.

sorry das wir dein problem nicht früher lösen konnten, aber die größte anzahl der oscat bausteine sind von zahlreichen anwender beigestellt, und werden auch von anwendern weiterentwickelt, es ist open source.
die idee ist das man nicht seinen eigenen schreibt sondern mithilft die oscat zu verbessern.

hugo

http://regregex.bbcmicro.net/crc-catalogue.htm

für alle die parameter für einen bestimmten CRC suchen ist dieser web link eine wahre goldgrube.
dort sind nicht nur die polynome gelistet, sondern auch die restlichen parameter wie init, xor, usw....
auch die checksumme für eine zeichenkette "0,1,2,3,4,5,6,7,8,9" ist angegeben so das CRC Bausteine einfach getestet werden können.

wir werden mit der nächsten relese (3.21) auch einen neuen crc baustein bringen der wesentlich schneller, weniger ressourcen benötigt und auch alle parameter eines CRC's unterstützt.