Moin Moin! Ich sitze hier an einem kleinen Problem. Vielleicht könnt ihr mir ja helfen. Für ein serielles proprietäres Protokoll muss ich eine CRC16 Checksumme berechnen. Dazu werden alle ASCII Zeichen zwischen dem Start und Ende Zeichen in die Berechnung mit einbezogen. Wenn ich nun eine kurze Meldung schicken will klappt die Berechnung auch wunderbar. Kurz bedeutet zwei Zeichen für Ziel, zwei Zeichen für Quelle und ein Zeichen als positive Quitierung. Wenn ich nun aber eine längere Meldung schicken will (z.B. beim Hochfahren zum Statusabgleich anfordern) dann bleibt die Checksumme Null. Es werden also 4 Bytes mit je 0x00 gesendet. Dies ist natürlich nicht richtig. Nach der klasse Webseite http://www.zorc.breitbandkatze.de/crc.html müsste die Checksumme "61CB" sein wenn ich das Datum "b2400000000000001" senden will. Nun meine Frage - habt ihr eine Idee wieso bei diesem Datum bei mir als Checksumme "0" rauskommt? Eingesetzt wird der ATmega128 von ATMEL mit dem CodeVisonAVR Compiler in der Version 1.25.7a. Das Board ist ein Entwicklungsboard der FTZ Leipzig. Zu finden unter http://www.easytoweb.net. Ich habe mal eine gekürzte Version meines Sourcecodes angehängt. In der Funktion minimax_quitierung() wird eine Checksumme berechnet die auch richtig ist. In der Funktion minimax_statusabgleich() wird auch eine CRC berechnet die aber den oben beschriebenen Fehler aufweist. Vielen Dank schonmal für eure Mühe. Gruß Björn Niethammer
Björn, in minimax_statusabgleich() hast du unsigned char crc_wert = 0x0000; geschrieben, was mir nicht richtig erscheint. Es müsste unsigned int sein. Ausserdem sehe ich nirgends eine Zuweisung der Art crc_word = (unsigned char *)(&crc_wert); damit auch der CRC-Wert gesendet wird. Ciao, Yagan
Hallo Yagan! Die Deklarierung der Variable hab ich testweise mal auf unsigned char gesetzt. Das war vorher immer unsigned int. Auch hab ich unsigned long getestet um einen Overflow auszuschließen. In allen Fällen kommt aber 0 als Ergebnis zurück. Die Zuweisung crc_word = (unsigned char *)(&crc_wert); erledige ich mit der Anweisung sprintf(crc_word,"%04X",crc_wert); Damit wird die Variable crc_wert auf crc_word gecastet, auf 4 Stellen begrenzt und in dem Fall, dass es weniger als 4 Zeichen sind führende Nullen eingefügt. In all meinen anderen Funktionen klappt das auch einwandfrei. Nur in der minimax_statusabgleich() nicht. Ich werde trotzdem mal deine cast Anweisung testen. Um Auszuschließen das es an der sprintf() Funktion liegt. Mal sehen was da rauskommt. Melde mich mit dem Ergebnis dann wieder zurück. Gruß Björn Niethammer
So ich habe mal die cast Anweisung crc_word = (unsigned char *)(&crc_wert); getestet. Leider kommt da zwar was raus aber nicht das was ich brauche. Das Protokoll sieht eine ASCII->HEX Darstellung. Also der HEX Wert des CRC wird in ACSII Zeichen gewandelt und übertragen. Wenn ich obige cast Anweisung nutze dann werden aber die HEX Werte übertragen. Somit bin ich auf die sprintf() Funktion angewiesen. Ich hab jetzt auch mal testweise den Wert von crc_wert manuell festgelegt. Auch dann gibt sprintf() Null als Wert für crc_word zurück. Gibt es bei sprintf() irgendwelche Einschränkungen oder Probleme weswegen es so ein Verhalten gibt?
Hallo Björn > Die Zuweisung > > crc_word = (unsigned char *)(&crc_wert); > > erledige ich mit der Anweisung > > sprintf(crc_word,"%04X",crc_wert); ok, das habe ich nicht beachtet. Dann liegt das Problem darin, dass crc_word nur als pointer deklariert ist, aber kein Speicher dahinter steht. Schreibe unsigned char crc_word[5]; // string für 4 chars CRC hexadezimal. dann müsste es allein mit sprintf(crc_word,"%04X",crc_wert); und uart_write_block(UART_DEV1,crc_word,4); funktionieren. Ciao, Yagan
Ohh super! Vielen vielen Dank Yagan. Das war tatsächlich das Problem. Mich wundert nur das es in all den anderen Funktionen wo ich auch die CRC Berechnung drinn habe es nicht zu diesem Fehler gekommen ist(siehe z.B. die minimax_quitierung() in dem Anhang). Na vielleicht war das auch nur Zufall das es klappte. Ich werde vorsichtshalber in allem Funktionen diese Zuweisung von Speicher mit reinnehmen. Erinnert mich auch irgendwie an meinen meistgemachten Fehler bei der Programmierung unter Linux. Wenn da was nicht ging war es meist ein vergessenes malloc(). ;-) Nochmal vielen Dank für deinen schnelle Hilfe. Weiter so! Gruß Björn Niethammer
Björn, dass es manchmal funktioniert, kann daran liegen, dass der pointer auf irgendeinen vorhandenen oder unbenutzten Speicherbereich zeigt. Dadurch können aber seltsame Nebeneffekte auftreten. Eigentlich müsste der Compiler eine Warnung absetzen, dass eine benutze Variable nicht initialisiert ist. Ciao, Yagan
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.