Forum: Mikrocontroller und Digitale Elektronik char to hex auf atmega1281v


von Manu (Gast)


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?
1
char buf = ConfigurationFrame[i-1];
2
char HexArray[2];
3
4
int NumWert = (int) buf;
5
int LowNum = NumWert % 16;
6
int HighNum = (NumWert -  LowNum) / 16;
7
8
if(HighNum >= 0 && HighNum < 10)
9
{
10
  HexArray[0] = (char) (HighNum + 48);
11
}
12
else if (LowNum > 9 && LowNum < 16)
13
{
14
  HexArray[0] = (char) (HighNum + 55);
15
}
16
else
17
{
18
  HexArray[0] = 'X'; // Fehler beim Umrechnen
19
}
20
if(LowNum >= 0 && LowNum < 10)
21
{
22
  HexArray[1] = (char) (LowNum + 48);
23
}
24
else if (LowNum > 9 && LowNum < 16)
25
{
26
  HexArray[1] = (char) (LowNum + 55);
27
}
28
else
29
{
30
  HexArray[1] = 'X'; // Fehler beim Umrechnen
31
}
32
33
write_uart0(HexArray[0]);
34
write_uart0(HexArray[1]);
35
write_uart0(' ');
36
37
write_uart1(HighNum);
38
write_uart1(LowNum);
39
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!

von Karl H. (kbuchegg)


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!

von Karl H. (kbuchegg)


Lesenswert?

ZU deinem Problem.
1
char toHexDigit( unsigned char nibble )
2
{
3
  if( nibble >= 0x0A )
4
    return nibble + 'A' - 0x0A;
5
6
  return nibble + '0';
7
}
8
9
void write_uart0_hex( unsigned char value )
10
{
11
  write_uart0( toHexDigit( ( value >> 4 ) & 0x0F ) );
12
  write_uart0( toHexDigit( value & 0x0F );
13
}

von Karl H. (kbuchegg)


Lesenswert?

1
int NumWert = (int) buf;
2
int LowNum = NumWert % 16;
3
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.

von Floh (Gast)


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!

von Manu (Gast)


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.

von Karl H. (kbuchegg)


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.

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.