Hallo Zusammen, ich brauch dringend Hilfe! Ich muss eine ASCII Zeichenkette in Hex-Notation umwandeln und dann die CRC16-XModem berechnen. Ich hab nun mal den online crc calculator von lammertbies benutzt und da wird das richtige Ergebnis angezeigt. Ich will also serielle Daten über den UART abfangen und in ein Array schreiben. Dann dieses Array in Hex umwandeln und aus diesen Zeichen die CRC-XModem berechnen. Ich bin noch neu in uC-Programmierung und hab meine Probleme mit der ganzen Sache.Ich würde mich freuen, wenn mir jemand weiterhelfen könnte. Grüße, Micha
Du hast also einfach 2 Aufgaben: > Ich muss eine ASCII Zeichenkette in Hex-Notation umwandeln Welche ASCII-Zeichen bekommst du? Woher? Und warum/wozu/wofür brauchst du da eine Hex-Darstellung davon? Die Hexdarstellung ist nämlich tatsächlich nur eine andere "Darstellung" eines Bitmusters. Der uC rechnet immer binär. Nur weil das für uns Menschen so unhandlich ist, wird das hilfsweise in andere Zahlensystemen dargestellt. Nehmen wir ein Byte mit 8 Bit. Das sieht der uC: 00010010 Im Hex-System ist das: 1 2 und dezimal: 34 Über eine serielle Schnittstelle würden dann z.B. die ASCII-Zeichen 1,2,cr,lf übertragen, oder auch 3,4,nul oder auch stx,3,4,etx Das ist nur eine Frage des Protokolls... > und dann die CRC16-XModem berechnen. Das kommt später...
Bist du dir sicher das du die Umwandlung in Hex brauchst? Hex ist nur eine Darstellung damit der Mensch die Werte besser lesen kann. Die CRC wird ja aus den binären Werten berechnet. Ansonsten kannst du bei printf mit %x Werte Hexadezimal ausgeben.
Hallo zusammen, danke für die Antworten. Also ich benötige die Berechnung der CRC wie sie der Calculator durchführt. Das Ergebnis passt. Sprich, er sieht die einzelnen Zeichen nicht als ASCII sondern als Hex-Zeichen (-->Hex-Input), oder?! A (ASCII) = 65dec A (HEX) = 10dec Ich empfange die Zeichen von einer Steuereinheit, an der ich die Daten über die Schnittstelle abfange und über einen Pegelwandler an den UART meines ATmega2560 weiterleite. Wie gesagt ich bin noch neu und die Realisierung des Ganzen, wäre momentan mein persönlicher Mount Everest.
Da du bei dem Calculator nicht das Zeichen mit dem Wert 10 eingeben kannst, wird der Umweg über die Hex-Darstellung genommen. Du musst aber mit der 10 rechnen. Sonst hast du 2 Zeichen die '0' und das 'A' (was dann wieder 2 Byte sind mit den Werten 48 und 65)
Hallo! @lkmiller Damit der Michael O. nicht verunsichert wird: 12H ist eigentlich immer 18dez gewesen und nicht 34dez.
Ah Ok, dann nimmt der Calculator also für A nicht 0100 0001, sondern einfach 0000 1010, also 10 dec. Für B = 11dec, usw. bis F = 15dec. Der Calculator interpretiert die ASCII Zeichen also als Hex-Zeichen. Wie rechne ich nun, wenn ich die Zeichen in einem Array vorliegen habe, das jetzt am besten um, sodass ich dann anschließend die CRC16-XModem berechnen kann, wo schon das nächste Problem liegt? Ufff,...
Wenn du den HexString zum Testen in deinen Calculator eingeben willst:
1 | int phex(char *s) |
2 | {
|
3 | while (s && *s) { |
4 | printf("%x", *s++); |
5 | }
|
6 | puts(""); |
7 | }
|
Aber Achtung: Die Funktion benötigt einen Null-Terminierten String.
Oder so!Hier kannst du die umgewandelten Zeichen übers HT ausgeben void aushgabehex8( unsigned char x) { if( (x >> 4) < 10 ) send( (x >> 4) + 0x30 ); else send( (x >> 4) + 0x37 ); if( ( x & 0x9f ) < 10 ) send( ( x & 0x0f ) + 0x30 ); else send( (x & 0x0f) + 0x37 ); }
Hallo, danke für die Antworten."Oderso", kannst du mir da vielleicht nochmal etwas weiterhelfen? Ich versteh deinen Ansatz nicht ganz. Gruß
Ich versuchs mal (x >> 4) heißt x um 4 (binäre) Stellen nach rechts verschieben. Das ist wie durch 16 teilen und ergibt das obere Nibble. + 0x30 meint in diesem Fall die ASCII '0' und ergibt eine ASCII-Ziffer + 0x37 meint in diesem Fall das ASCII 'A' - 10 und ergibt eine ASCII-Buchstaben ( x & 0x0f )lässt nur die unteren 4 Bits stehen und ergibt das untere Nibble.
1 | void aushgabehex8( unsigned char x) |
2 | {
|
3 | if( (x >> 4) < 10 ) // Wenn das obere Nibble < 10 ist |
4 | send( (x >> 4) + 0x30 ); // addiere '0' dazu. Damit hast du eine Ziffer |
5 | |
6 | else send( (x >> 4) + 0x37 ); // addiere 'A'-10 dazu. Damit hast du einen Buchstaben |
7 | // Das Gleiche für das untere Nibble.
|
8 | if( ( x & 0x9f ) < 10 ) // Tippfehler soll 0x0f sein. |
9 | send( ( x & 0x0f ) + 0x30 ); |
10 | |
11 | else send( (x & 0x0f) + 0x37 ); |
12 | |
13 | }
|
Das geht auch mit
1 | const char hexziffer* = "0123456789ABCDEF" |
2 | |
3 | void aushgabehex8( unsigned char x) |
4 | {
|
5 | send( hexziffer[x >> 4]; // oder [(x >> 4) & 0x0f] |
6 | send( hexziffer[x & 0x0f]; |
7 | }
|
Hallo Dirk, vielen Dank für deine Antwort! Ok, ich kann also mit dem Code von Oderso auch die Einzelnen Zeichen in Hex umwandeln. Gut, wenn ich nun mein umgewandelten String in Hex vorliegen hab, wie kann ich dann die CRC16 - XModem ausrechnen bzw., wie muss ich vorgehen?
Nochmal: Du brauchst keinen in Hex umgewandelten String um die CRC zu berechnen. Das ist nur eine Hilfe um deas in den Calculator zu bekommen. Du musst für die Berechnung die Rohwerte nehmen. So wie das Zeichen/Byte im Array steht. Schon mal Forensuche oder Wikipedia zum Theme CRC bemüht?
Oh mann, sorry, falsch formuliert! OK, ich rechne nicht den String um sondern die einzelnen Zeichen! Also Bei der Eingabe von "A"berechne ich bei ASCII 0100 0001 und bei der von A als Hex, rechne ich mit 0000 1010. Ich binde jedes Byte zur Berechnung mit ein...Das verstehe ich schon. Allerdings häng ich bei der Realisierung der CRC-Berechnung. Ich wandle jedes Zeichen um und schrieb es in ein Array. Jetzt hab ich nun mein Array mit den umgewandelten bytes. Wie muss ich weiter vorgehen? Danke nochmal für die Antworten und Tipps! VG
(unter anderem) Vor über 8 Jahren wurde das Problem hier schon gelöst unter dem Titel "Suche CRC16".
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.