Forum: Mikrocontroller und Digitale Elektronik Konvertierung in hex


von Sam (Gast)


Lesenswert?

hallo,

Will eine 8bit variable, in meinem Fall ist das die CheckSumme über den 
UART(2te serielle) Schicken.

Die CheckSumme ist eine Varible die durch XORen von Zeichen, errechent 
wird.

CheckSumme = CheckSumme ^ *checkpointer;
Printf(„%X“, CheckSumme); // ergibt einen hex.wert z.B. 13,
1 = hight-nibble und  3= low-nibble.

Übertrage ich den Wert der CheckSumme in den Buffer des UARTs und lasse 
ihn ausgeben(durch Hyperterminal), wird mir nur ein Zeichen ausgegeben.
Desshalb habe ich die CheckSumme in ein hight-nibble und ein low-Nibble 
umgewandelt und in einen Buffer abgelegt:

// alle variablen sind vom typ unsigned Char

checkhight = CheckSumme >> 4;    // hight-Nibble, CheckSumme bsp. 1011 
0111
checklow = CheckSumme & 0x0F;  // low-Nibble,     0000 0111

printf(“%X”,CheckSumme);        // Kontrollausgabe, 1ste serielle

WriteBuffer[check++]  = checkhight; //checksumme Hight nibble   0000 
1011
WriteBuffer[check++]  = checklow;   //checksumme low nibble    0000 0111
WriteBuffer[check++] = '\r';
WriteBuffer[check++] = '\n';
....
....
writepointer = WriteBuffer;
UARTBuffer = *writepointer;  //ausgabe 2te serielle
writepointer++;
..
..
..
Trozdem wird mir ein falsches zeichnen ausgegeben.
z.B. für die Ausgabe 13(hex) wird  ┌└  (Chr) in der 2ten seriellen 
Ausgegeben. Allgemein sollen nur zeichen von 0...9, A....Z, a....z
Weiß einer wie man das lösen kann.
Ich weiß das printf("%X",CheckSumme); in hex. Konvertiert und mir 
desshalb den erwünschen hexwert ausgibt, aber wie kann ich diesen 
abspeichern und verwenden??

Ich verwende als eingabe und ausgabe den Hypertterminal.

danke

von Peter B. (pbuenger)


Lesenswert?

> Ich weiß das printf("%X",CheckSumme); in hex. Konvertiert und mir
> desshalb den erwünschen hexwert ausgibt, aber wie kann ich diesen
> abspeichern und verwenden??

Mit "sprintf" statt "printf".

Gruß,
Peter

von Gast (Gast)


Lesenswert?

checkhight und checklow sind keine ASCII Zeichen. Addiere 0x30 bzw "0" 
dazu.

von Gast (Gast)


Lesenswert?

oh ne, sorry das Addieren geht ja nur bei Dezimalzahlen.

von Aubacke007 (Gast)


Lesenswert?

Hi,

meines Wissens gibt das Hyperterminal von Windows nur ASCII Zeichen aus. 
Der Wert 0x13 ist dann wohl das von dir genannte Zeichen. Eine 
Umstellung der Anzeige ist im Hyperterminal nicht möglich.

Dieses problem hatte ich auch einmal und bin dann auf das Programm HTerm 
umgestiegen, welches man frei downloaden kann. hier kannst du dann eine 
Umstellung der ANzeige ziemlich komfortabel vornehmen (Dez, Bin, Hex).

Sollte dir helfen...
Grüße

von Yagan Ζ. D. (yagan)


Lesenswert?

Sam,

mit
1
checkhight = CheckSumme >> 4;    // hight-Nibble, CheckSumme bsp. 1011
2
checklow = CheckSumme & 0x0F;  // low-Nibble,     0000 0111
3
WriteBuffer[check++]  = checkhight; //checksumme Hight nibble   0000
4
WriteBuffer[check++]  = checklow;   //checksumme low nibble    0000 0111

erzeugts du die Checksumme in binärer Form und nicht in ASCII, wie du es 
haben willst.

Einfache Lösung:
1
const char *sBinToHex = "0123456789ABCDEF";
2
3
WriteBuffer[check++]  = sBinToHex[(CheckSumme>>4)&0x0F]; //checksumme High
4
WriteBuffer[check++]  = sBinToHex[CheckSumme & 0x0F]; //checksumme low

Mit dem String sBinToHex kannst du alle 4-Bit Binärwerte als 
ASCII-Zeichen in hexadezimaler Form darstellen.

Ciao, Yagan

von Sam (Gast)


Lesenswert?

mein prob ist das ich auch nur ASCII ausgeben will.
Und zwar nur 0...9, A...Z, a....z.
wenn ich z.B. 0x30 dazu addiere kriege ich dann die ganzen steurzeichen 
weg.
Aber wieso geht das nicht mit hex.?? muß man dan erstes in Dec. 
konvertieren?? und dan addieren?? und als letzten schritt wieder in hex 
konvertieren??

von Sam (Gast)


Lesenswert?

Yagan, das klingt gut mal testen. ;-)

von Gast (Gast)


Lesenswert?

Schau dir mal eine ASCII Tabelle an. Speziell wo die Zahlen und wo die 
Buchstaben liegen dan hast du die erklärung auf deine letzten Fragen.

von Reinhard R. (reirawb)


Lesenswert?

Das Teilen der Nibbel ist schon richtig, dein Terminal gibt allerdings 
ASCII-Zeichen aus. Schau dir mal eine ASCII-Tabelle an und überleg mal, 
wie du die gewünschten Zeichen generieren könntest.

> checkhight = CheckSumme >> 4;    // hight-Nibble, CheckSumme bsp. 1011 0111
> checklow = CheckSumme & 0x0F;  // low-Nibble,     0000 0111

Hier müsste folgender Code folgen (musst du sicher anpassen, ich bin der 
Sprache C leider noch nicht mächtig, ich mach sonst Assembler):

if checkhigh < 0x0A then
   checkhigh = checkhigh + 0x20 ; für die Ausgabe 0...9
else
   checkhigh = checkhigh + 0x41 ; für die Ausgabe A...F
end

if checklow < 0x0A then
   checklow = checklow + 0x20 ; für die Ausgabe 0...9
else
   checklow = checklow + 0x41 ; für die Ausgabe A...F
end

Gruß Reinhard

von Sam (Gast)


Lesenswert?

Yagan es klappt. echt geil. und ohne große schleiferei. Danke

Jetzt was zu verständigung.

const char *sBinToHex = "0123456789ABCDEF";
WriteBuffer[check++]  = sBinToHex[(CheckSumme>>4)&0x0F]; was passiert 
eigenlich hier???

von Yagan Ζ. D. (yagan)


Lesenswert?

Sam,

der String sBinToHex enthält alle vorkommenden Zeichen für die 
Hex-Darstellung der Werte 0 bis 15, Deklaration als Konstante (Zeiger 
auf "012...F").

Mit sBinToHex[(CheckSumme>>4)&0x0F] wird auf den String indiziert 
zugegriffen, d.h. als Index wird der Binärwert (0-15) benutzt, das 
Ergebnis ist das passende ASCII-Zeichen (z.B. sBinToHex[0] liefert '0', 
sBinToHex[15] liefert 'F').
Statt der Index-Schreibweise sBinToHex[15] könnte man auch die 
Pointer-Schreiweise *(sBinToHex+15) benutzen. Das Ergebnis wäre 
identisch.

Mit (CheckSumme>>4)&0x0F werden die "oberen" 4 Bits von Checksumme 
extrahiert und so zurechtmaskiert, dass als Index nur 0-15 entstehen 
kann (weil der String nur 16 Zeichen enthält). &0x0F ist in diesem Fall 
eigentlich redundant, aber wenn CheckSumme kein 8-Bit-Wert ist, 
funktioniert die Formel auch.

Ciao, Yagan

von eProfi (Gast)


Lesenswert?

Du kannst es aber auch ohne Tabelle machen, nur mit Rechnen:

unsigned char tmp;
WriteBuffer[check++] = ((tmp=CheckSumme>>4)<10)?tmp+'0':tmp+'7';
WriteBuffer[check++] = ((tmp=CheckSumme&15)<10)?tmp+'0':tmp+'7';

Ungetesteter Code!
Zur Funktion:
wenn das Nibble <10, also 0..9 ist, wird 0x30 addiert
wenn das Nibble >10, also a..f ist, wird 0x37 addiert, also kommt für A 
0x0a+0x37=0x41 (10+55=65) raus, genau wie gewünscht ein 'A'.

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.