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
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
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ß
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 ); ... }
@KarlHeinz Vielen Dank. Dein Code funktioniert super und ist weit aus performanter als itoa Besten Gruss H:V
Was mir gerad noch aufgefallen ist: Es muss if( Nibble >= 10 ) - heissen, sonst wird das A als : dargestellt. Gruss
Tschuldigung. Hatt den Code ohne ihn zu testen ins Forum reingeklopft. Ich würde es so schreiben if( Nibble > 9 )
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().
1 | //*** Hex-Darstellung:
|
2 | PROGMEM uint8_t hexval[] = "01234567890ABCDEF"; |
3 | |
4 | uint8_t* hex(uint8_t val, uint8_t *s){ |
5 | *s = pgm_read_byte(hexval + ((val>>4) &0x0F)); |
6 | *(s+1) = pgm_read_byte(hexval + (val &0x0F)); |
7 | *(s+2) = 0; |
8 | return(s); |
9 | }
|
Viel Spass, Stefan
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 ;)
> 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.
Ok, dann ist es nicht ganz so wild wenns ausm ROM kommt. BTW: Muss ich PROGMEM Deklarationen global lagern?
Na, die Alternative wäre noch static auf Modul- oder Funktionsebene. Automatisch geht nicht ... wie auch?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.