mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik char to hex auf atmega1281v


Autor: Manu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich will unter anderem mit dem atmega1281 einen char in eine 
hex-darstellung überführen. Das Problem ist im Moment, dass größere 
Werte (z.B.: 161, 0xA1) nicht richtig angezeigt werden. Für das 
höherwertige Nibbel bekomme ich so als Dezimalzahl 251 (sollte 10 = A 
sein) und für das zweite 241 (sollte 1 sein), welche ich natürlich nicht 
in eine einzelne hex-Zahl (0-F) umrechnen kann. ist das msb nicht '1' 
klappt die Umrechnung.
Was hab ich falsch gemacht?
char buf = ConfigurationFrame[i-1];
char HexArray[2];

int NumWert = (int) buf;
int LowNum = NumWert % 16;
int HighNum = (NumWert -  LowNum) / 16;

if(HighNum >= 0 && HighNum < 10)
{
  HexArray[0] = (char) (HighNum + 48);
}
else if (LowNum > 9 && LowNum < 16)
{
  HexArray[0] = (char) (HighNum + 55);
}
else
{
  HexArray[0] = 'X'; // Fehler beim Umrechnen
}
if(LowNum >= 0 && LowNum < 10)
{
  HexArray[1] = (char) (LowNum + 48);
}
else if (LowNum > 9 && LowNum < 16)
{
  HexArray[1] = (char) (LowNum + 55);
}
else
{
  HexArray[1] = 'X'; // Fehler beim Umrechnen
}

write_uart0(HexArray[0]);
write_uart0(HexArray[1]);
write_uart0(' ');

write_uart1(HighNum);
write_uart1(LowNum);
write_uart1(buf);
Ausgeben lass ich über den einen UART den Hex-Wert wie er nachher 
angezeigt werden soll. Über UART1 gebe ich als Integer die erste und 
zweite hex-Zahl und das ursprüngliche char aus.

Ausgabe UART0: 0xXX
Ausgabe UART1: 251,241,161


Danke!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die wichtigste Lektion, die du lernen musst

Es gibt in C 3 Datentypen, die alle letztendlich so was wie 'ein Byte' 
bedeuten

  *  unsigned char
     das ist der Datentyp, wenn du mit Bytes hantieren willst.
     Du willst auf keinen Fall irgenein Vorzeichen oder dass sich
     das Vorzeichenbit auf die Verarbeitung, wie zb beim Rechtsschieben
     auswirkt.

     unsigned char ist der Datentyp in dem Bits einfach nur Bits sind.


  * signed char
    den benutzt du, wenn du so etwas wie 'einen kleinen Integer'
    im Zahlenbereich -128 bis +127 benötigst.

  * char
    char benutzt du ausschliesslich und nur dann, wenn
    + du nicht großartig rechnen musst
    + es bei der Verarbeitung um Zeichenverarbeitung im Sinne von
      Textbehandlung geht.

    Ansonsten benutzt du auf keinen Fall 'char'. Bei char kann sich
    der Compiler aussuchen, ob der signed oder unsigned sein kann.
    Und diese Wahl überlässt du auf keinen Fall dem Compiler!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ZU deinem Problem.
char toHexDigit( unsigned char nibble )
{
  if( nibble >= 0x0A )
    return nibble + 'A' - 0x0A;

  return nibble + '0';
}

void write_uart0_hex( unsigned char value )
{
  write_uart0( toHexDigit( ( value >> 4 ) & 0x0F ) );
  write_uart0( toHexDigit( value & 0x0F );
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int NumWert = (int) buf;
int LowNum = NumWert % 16;
int HighNum = (NumWert -  LowNum) / 16;

Nimm mal Zahlen an und überprüfe, was da rauskommt.
Insbesondere die letzte Berechnung ist falsch :-)

Im letzten Posting hab ich dir aber gezeigt, wie man das besser macht.

Ach ja, noch was:
Benutze nicht die ASCII Codes (noch dazu in dezimaler Schreibweise), 
wenn du genausogut mit den Characters selber arbeiten kannst.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void lcdh8(char* &c, uint8_t val)
{
  *c = ((val&0xF0)>>4)+'0';  //obere haelfte
  if(*c > '9')
    *c += ('A'-'9'-1);
  c++;
  *c = (val&15)+'0';         //untere haelfte
  if( *c > '9')
    *c += ('A'-'9'-1);
}

Der tut bei mir :-)
Aber Vorsicht, es wird an ein Array mit mindestens 2 chars erwartet und 
es wird kein Null-Byte angehängt!

Autor: Manu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Karl Heinz,
das war's ,-)
Hätte ich selber drauf kommen müssen!
Ein  anderer kleiner Fehler war auch noch drin:
Hatte beim ersten else if noch LowNum statt HighNum in der Bedingung 
stehen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Manu schrieb:
> Danke Karl Heinz,
> das war's ,-)
> Hätte ich selber drauf kommen müssen!
> Ein  anderer kleiner Fehler war auch noch drin:
> Hatte beim ersten else if noch LowNum statt HighNum in der Bedingung
> stehen.

Genau das ist zb einer der Gründe, warum man nicht jeden Sch... immer 
wieder neu auscodiert, sondern sich Funktionen für Aufgaben schreibt.

Du hast dich mit deinem Code ganz einfach selbst ausgetrickst, indem du 
ihn unnötig unübersichtlich geschrieben hast.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.