Bascom CRC16 - Ich krieg die Krise.

Gast #1537928
Lesenswert?

Moin,

ich habe hier eine (funktionierende) Funkübertragung.
Gesendet wird ein Array (Word*5).

Array(5)...Array(2) sind Daten, Array(1) ist die per Bascom-Funktion 
errechnete CRC16 über Array(5)...Array(2).

Vergleiche ich im Empfänger gesendete und neu berechnete CRC, sind sie 
identisch. Fein.

Rechne ich die CRC16 über das gesamte Array, sollte dann "0" 
herauskommen.
Tut es aber nicht....

Der Programm-Code sieht so aus:
1
Cks = Crc16(rx_telegram(1) , 10)
2
Cks_tx = Rx_telegram(1)
3
Cks_rx = Crc16(rx_telegram(2) , 8)

Der Empfänger gibt z.B. folgendes per Terminal aus:
1
Cks = 5746
2
Cks_tx = 33491
3
Cks_rx = 33491

Welche Dusseligkeit mache ich hier?

Ratlose Grüße aus der Wesermarsch

Ralph

PS: Die Cks... sind alle als "Word" definiert.
Gast #1537994
Lesenswert?

Ohne mehr Quellcode ist es wie immer schwierig...

Hier mal ein paar Anregungen:

Die CRC16 Checksumme ist 2 Byte lang, also word oder integer.

Cks_tx = Rx_telegram(1)
Da wird einer Word-Variablen ein Byte zugewiesen?

Falls rx_telegramm(2) aus Bytearray ist, müßte das
Cks_rx = Crc16(rx_telegram(3) , 8), oder falls WordVar
Cks_rx = Crc16(rx_telegram(2) , 4) heissen.

MFG
screwdriver
Gast #1538069
Lesenswert?

screwdriver schrieb:
> Cks_rx = Crc16(rx_telegram(2) , 4) heissen.

Das war Unsinn.

Um ein Array inklusive CRC-Checksumme auf Null zu testen, muß die 
Checksumme zuletzt durch den CRC-Generator laufen, d.h. die 
CRC-Checksumme muß in der Variablen Array(5) stehen. Ausserdem sind LSB 
und MSB zu vertauschen.

Beispiel:
1
Dim Array(5) As Word
2
Dim Bytearray(10) As Byte At Array(1) Overlay
3
Dim Wtemp As Word
4

5
Array(1) = 1
6
Array(2) = 3
7
Array(3) = 5
8
Array(4) = 7
9

10

11

12
Array(5) = Crc16(bytearray(1) , 8)
13
Print Array(5)
14

15
Wtemp = Array(5)
16
Bytearray(9) = High(wtemp)
17
Bytearray(10) = Low(wtemp)
18

19
Wtemp = Crc16(bytearray(1) , 10)
20
Print Wtemp
21

22
Do
23
Loop
Gast #1538080
Lesenswert?

Moin screwdriver,

screwdriver schrieb:
> Ohne mehr Quellcode ist es wie immer schwierig...

Na, ob der Bandwurm (mitten in der Bastelphase) mehr Klarheit 
brächte...:-)


> Die CRC16 Checksumme ist 2 Byte lang, also word oder integer.

Klar; ist als Word definiert.

> Cks_tx = Rx_telegram(1)
> Da wird einer Word-Variablen ein Byte zugewiesen?

Nö. Rx_telegram ist wie folgt definiert:

dim rx_telegram(5) = word

rx_telegram(1) ist das erste Element des Array, also ne Word-Variable.

> Falls rx_telegramm(2) aus Bytearray ist, müßte das
> Cks_rx = Crc16(rx_telegram(3) , 8), oder falls WordVar
> Cks_rx = Crc16(rx_telegram(2) , 4) heissen.

Hm. Ich verstehe die Bascom-Hilfe anders.

Sei a = Crc16(b , c),

dann ist "b" das erste Element zur CRC-berechnung (also ne Word, 
genauer rx_telegram(1)) und c die Anzahl der Bytes. Oder bin ich genau 
hier auf dem Holzweg?

Cks_rx und Cks_tx werden ja auch völlig korrekt berechnet und sind 
(fast) immer gleich.

Lediglich die CRC16 über das gesamte Telegramm (also incl. Checksumme in 
rx_telegram(1)) wird nicht null. Was es werden sollte, wenn ich den 
Algorithmus richtig verstanden habe...

Danke fürs Gedanken-machen!


Ralph
Gast #1538122
Lesenswert?

Moin,

da haben wir uns überschnitten.

screwdriver schrieb:


> Um ein Array inklusive CRC-Checksumme auf Null zu testen, muß die
> Checksumme zuletzt durch den CRC-Generator laufen,

Ahaaa....
Das wäre die Erklärung.

Das probiere ich gleich mal aus. An den Sender komme ich gerade nicht 
heran (der liegt zum Dauertest draußen im Schnee), da werde ich mal eben 
im Empfänger ein bisschen pfuschen.

Ich sach dann Bescheid :-)

Ralph
Gast #1538171
Lesenswert?

Bescheid!

So, jetzt habe ich mal ein neues Test-Array angelegt, mit den Daten des 
empfangenen Telegramms passend befüllt und das oberste Element um 8 
rotiert.

Bingo!
Die Prüfsumme ist auf wundersame Weise null.

Ganz herzlichen Dank!

Ralph

der sich jetzt diesem mistigen PCF8583 zuwenden kann. Das Ding will auch 
nicht sowie ich es gerne hätte.
Gast #1538200
Lesenswert?

Ralph Fischer schrieb:
> ....und das oberste Element um 8 rotiert.

Nur zur Info:

rotate wtemp,righ,8
-> 75 Cycles

rotate wtemp,left,8
-> 68 Cycles

Wtemp = Array(5)
Bytearray(9) = High(wtemp)
Bytearray(10) = Low(wtemp)
-> 30 Cycles

Falls mal eng werden sollte!

screwdriver
Gast #1538237
Lesenswert?

Ich noch mal...

screwdriver schrieb:
> Wtemp = Array(5)
> Bytearray(9) = High(wtemp)
> Bytearray(10) = Low(wtemp)
> -> 30 Cycles

Dankeschön :-)
Gut zu wissen.

Allerdings verbringt der Controller eh die meiste Zeit mit Nasebohren 
(bzw. Warten darauf, daß alle paar Minuten ein Telegramm eintrudelt).

Die gesamte Auswertung passiert noch mit Floats; eigentlich ein 
Wahnsinn.

Aber so langsam läuft der ganze Kram (soll ein Telemetriesystem 
(RFM01/02) für bis zu 32 Sender mit verschiedenen Sensoren werden).

Dann gehts ans Aufräumen. Zumindest der Empfangsstart wird dann in ne 
ISR gepackt.

Sollte es mal richtig eng werden, muß ich halt meine 
Assembler-Kenntnisse modernisieren.
Die sind gut 25 Jahre eingerostet (Z80) ;-)

Jucken würden mich diese Risc-Teile ja schon...

Danke noch mal!

Ralph

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren