mikrocontroller.net

Forum: Compiler & IDEs Hex Zahl als solche ausgeben


Autor: Hr. Vorragend (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich habe ein Unsigned Char welches eine Zahl zwischen 0 und 15
enthaelt.

Wenn ich diese nun über den UART ausgebe, erhalte ich nur die ersten 16
Sonderzeichen der Ascii Tabelle.
Wenn ich die Zahl mit 48 addieren wuerde, wuerden die Zahlen richtig
ausgegeben, aber die Hex Buchstaben nicht da in der Ascii Tabelle die
Buchstaben nicht direkt nach den Zahlen folgen.

Wie kann ich das einfach lösen?


Gruss

H:V

Autor: Hr. Vorragend (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry,
ich muss mich korrigieren.

Ich habe eine unsigned char zahl von 0-255 und diese soll als Hexcode
von 00-FF ausgegeben werden. Wie ist das möglich? Nur mit snprintf?



Gruss

Autor: A65power (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
also die Zahlen werden nacheinander im 8-Bit format Bit für Bit
übertragen. D.H. das ist Einstellungssache deines Terminalprogramms.

Beispiel:
Dezimal:   57
Binär:   0011 1001
Hexadez.:    39
ASCII:        9

Ich selbst kenne den Befehl nicht.
Ein Terminal, welches ich gerne nutze ist das von
http://www.docklight.de/
Bei diesem kann das Anzeigeformat eingestellt werden.
Gruß

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
snprintf wäre eine Möglichkeit. Das entsprechende Formatiersymbol
lautet %x
itoa (falls ist eine andere).

Oder aber du schreibst dir selbst was:

unsigned char HexNibble( unsigned char Nibble )
{
  if( Nibble > 10 )
    return Nibble - 10 + 'A';
  else
    return Nibble + '0';
}

void ToHex( unisgned char Number, char* Out )
{
  Out[0] = HexNibble( ( Number >> 4 ) & 0x0F );
  Out[1] = HexNibble( Number & 0x0F );
  Out[2] = '\0';
}

void main()
{
  char HexASCII[3];
  unsigned char i = 198;

  ToHex( i, HexASCII );

  ...
}

Autor: Hr. Vorragend (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@KarlHeinz

Vielen Dank. Dein Code funktioniert super und ist weit aus performanter
als itoa


Besten Gruss


H:V

Autor: Hr. Vorragend (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir gerad noch aufgefallen ist:

Es muss
if( Nibble >= 10 )
            -
heissen, sonst wird das A als : dargestellt.


Gruss

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

Bewertung
0 lesenswert
nicht lesenswert
Tschuldigung.
Hatt den Code ohne ihn zu testen ins Forum reingeklopft.

Ich würde es so schreiben

   if( Nibble > 9 )

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe noch eine andere Variante.
Gut zu erkennen: meine Vorliebe für Tabellen.
Der Nachteil beim AVR ist das leidige Verwenden von PROGMEM und
pgm_read_byte().
//*** Hex-Darstellung:
PROGMEM uint8_t hexval[] = "01234567890ABCDEF";

uint8_t* hex(uint8_t val, uint8_t *s){
  *s     = pgm_read_byte(hexval + ((val>>4) &0x0F));
  *(s+1) = pgm_read_byte(hexval + (val &0x0F));
  *(s+2) = 0;
  return(s);
}

Viel Spass, Stefan

Autor: Christian Wolf (clupus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke mal, die 2. Null muss da weg, oder?

MfG
Christian

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian,

ja klar, stimmt. Danke!

Gruß, Stefan

Autor: Markus Stehr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würds lieber im Speicher lagern lassen, oder wieviele Zyklen frisst
ein Variablenzugriff per pgm_read_byte(pointer);?
Dann würde das dann so aussehen:

      //*** Hex-Darstellung:
      uint8_t* hex(uint8_t val, uint8_t *s)
      {
          static uint8_t hexval[] = "01234567890ABCDEF";
          *s = hexval[(val>>4) &0x0F];
          *(s+1) = hexval[val &0x0F];
          *(s+2) = 0;
          return(s);
      }

Ist natürlich nur interesannt wenn diese Hexausgabe nicht lange dauern
darf und mehr als wie nur so 8 Bytes umgewandelt werden müssen.
Am C64 Coden üben zahlt sich aus, so ähnlich würde das bei mir auch in
ASM aussehen zwecks Geschwindigkeitsgründen ;)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich würds lieber im Speicher lagern lassen, oder wieviele Zyklen
> frisst ein Variablenzugriff per pgm_read_byte(pointer);?

LPM braucht drei Zyklen pro Befehl, LDS braucht zwei Zyklen pro Befehl
aus dem internen SRAM, drei Zyklen aus dem externen.

Autor: Markus Stehr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann ist es nicht ganz so wild wenns ausm ROM kommt.

BTW: Muss ich PROGMEM Deklarationen global lagern?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, die Alternative wäre noch static auf Modul- oder Funktionsebene.
Automatisch geht nicht ... wie auch?

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.