Forum: Mikrocontroller und Digitale Elektronik ASCII-Zeichenkette in Hex umwandeln und CRC-16 XModem berechnen


von Michael O. (Gast)


Angehängte Dateien:

Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von DirkB (Gast)


Lesenswert?

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.

von Michael O. (Gast)


Lesenswert?

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.

von DirkB (Gast)


Lesenswert?

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)

von Route_66 (Gast)


Lesenswert?

Hallo!
@lkmiller
Damit der Michael O. nicht verunsichert wird: 12H ist eigentlich immer 
18dez gewesen und nicht 34dez.

von Michael O. (Gast)


Lesenswert?

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,...

von DirkB (Gast)


Lesenswert?

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.

von Oderso (Gast)


Lesenswert?

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 );

}

von Michael O. (Gast)


Lesenswert?

Hallo,
danke für die Antworten."Oderso", kannst du mir da vielleicht nochmal 
etwas weiterhelfen? Ich versteh deinen Ansatz nicht ganz. Gruß

von DirkB (Gast)


Lesenswert?

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
}

von Michael O. (Gast)


Lesenswert?

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?

von DirkB (Gast)


Lesenswert?

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?

von Michael O. (Gast)


Lesenswert?

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

von DirkB (Gast)


Lesenswert?

(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
Noch kein Account? Hier anmelden.