www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega128: Umwandeln von HEX in ASCII


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte über ein Display einige, im MC gespeicherte, Zahlen
ausgeben.
Diese sind aber im 2-stelligen Hex-Format (also 8bit).
Weiß jemand, wie ich diese Hex-Zahlen in jeweils 3 ASCII-Zeichen
umwandeln kann?
Gibt eis da einen Trick, oder brauche ich da eine Tabelle?

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Thema war hundertmal da.

Es gibt fertigen Code für wohl jede Programmiersprache auf der Welt (Du
verrätst ja nicht, welche Sprache auf welchem Gerät Du einsetzt).

Im aller-allerschlimmsten Fall mußt Du Dein Gehirn benutzen.
Denkansatz: beginne mit dem ASCII-Zeichen für null ($30). Solange Du
von der Zahl hundert abziehen kannst, tu es und erhöhe jedesmal den
ASCII-Wert. Wenn Deine Zahl dann unter hundert ist, kannst Du den
ersten Wert rausschreiben und beginnst wieder mit $30, diesmal mit den
Zehnern. Usw.

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
'Tschuldigung: der µC steht ja im Betreff, nur die Sprache finde ich
nicht.

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht evtl. auch noch einfacher, aber ich habe es in C mal so gemacht:
die Variable enthält die Zahl 145.
1. 145%10=5  -> einer
2. 145/10=14
3. 14%10=4   -> zehner
4: 14/10=1   -> hundetrter
Die Ergebnisse mit einem Offset beaufschlagen, der sich nach dem
Character-ROM des Displays richtet.

MW

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Variante mit der Division klingt eigentlich recht einfach.
Allerdings programmiere ich mit dem AVR-Assembler.
Ich muss mal schauchen, obs da die Möglichkeit zur Modulo-Division
gibt...

Autor: Jens D. (jens) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
3te Klase Mathematik teilen von zahlen

111 / 10 = 11 (rest1)
110
_
  1

Autor: dds5 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt auch noch andere Varianten, z.B. für jedes gesetzte Bit des
Quellregisters den entspr. dezimalen Wert (1,2,4,8,16,usw.) auf
Zielregister addieren und nach jeder Addition eine Dezimalkorrektur
("DAA" oder so) ausführen.
Das ergibt gepacktes BCD, muss man noch entpacken und jeweils 30h
dazuzählen, dann ists ASCII.

Dieter

Autor: Mike Schaub (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ein kleines Progrämmchen!


void itohexa(unsigned int n, unsigned char * s)    // wandelt eine long
Zahl in einen 4 Byte grossen HEX-String
{
  unsigned int  help,z;

  help = n;

  for (z=3;z>0;z--)
    {
      if ((help & 0x000F) > 9) s[z] = (help & 0x000F) + 55;
      else s[z] = (help & 0x000F) + '0';
      help = help >> 4;
    }

  s[4] = 0;
}


Gruß
Mike

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael: Schön in Hochsprachen, wenn man viel Zeit hat. Aber Division
und Modulo gibt es auf einem AVR nicht geschenkt.

@Jens: Hast Du den Eindruck, daß Bernd das hinbekommt, wenn ihm schon
subtrahieren zu schwierig ist?

@dds5: Wetten, daß das langsamer ist und mehr Takte braucht?

@Mike: Schön, war aber nicht verlangt.

@Bernd: Gerade wenn Du Assembler schreibst, vertraue mir: das
beschriebene Verfahren ist das einfachste. Ehrlich.

Aus dem Stegreif; die Zahl stehe in r16:

  ldi r17, $30 - 1 ; ein inc kommt immer!
Hunderterschleife:
  inc r17
  subi r16, 100
  brpl Hunderterschleife
  subi r16, -100 ; weil einmal zuviel abgezogen

  ldi r18, $30 - 1 ; ein inc kommt immer!
Zehnerschleife:
  inc r18
  subi r16, 10
  brpl Zehnerschleife

  ldi r18, $30 + 10 ; weil 10 zuviel von r16 abgezogen
  add r18, r16

Ich hoffe, das stimmt alles; das Ergebnis steht dann in r17,r18,r19. 11
Befehle. Ich bezweifle, daß man das mit Modulo oder anderen Methoden
hinbekommt. Und schneller sollte es auch sein.


Im übrigen meine Bewunderung für ein Mega128-Projekt in Assembler!

Autor: dds5 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Philipp
Ich hab sowas für 16Bit auf PIC18F in Assembler realisiert.
Ergibt knapp doppelt so viel Code wie die Subtraktion in Schleifen, ist
aber worst case (65535) rund doppelt so schnell.

Dieter

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm. Worst case für meine Schleife sollte bei 16 Bit übrigens 59999 sein.
Und dann ist noch die Frage, ob Durchschnitt (für max. Durchsatz) oder
Maximum (für real time scheduler!) wichtiger sind.

Ich kann es mir immer noch nicht richtig vorstellen, immerhin muß nach
jeder von bis zu 15 Additionen auf bis zu 5 Stellen auf Dezimalüberlauf
getestet werden.

Kannst Du auch AVR-Assembler? Dann steht meine Wette, daß Dein
Verfahren nicht mithält, selbst mit doppelt soviel Code. Auch nicht bei
16 Bit! Schlägst Du ein?

Gruß, Philipp.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal 16 Bit zu ASCII:
;*************************************************************************
;*                                                                     
 *
;*                      Convert unsigned 16 bit to ASCII               
 *
;*                                                                     
 *
;*              Author: Peter Dannegger                                
 *
;*                      danni@specs.de                                 
 *
;*                                                                     
 *
;*************************************************************************
;
;input: R17, R16 = 32 bit value 0 ... 65535
;output: R20, R19, R18, R17, R16 = 5 digits (ASCII)
;cycle: 20 ... 170
;
bin16_ascii:

        ldi     r20, 1- + '0'
_bcd1:  inc     r20
        subi    r16, low(10000)         ;-10000
        sbci    r17, high(10000)
        brcc    _bcd1

        ldi     r19, 10 + '0'
_bcd2:  dec     r19
        subi    r16, low(-1000)         ;+1000
        sbci    r17, high(-1000)
        brcs    _bcd2

        ldi     r18, -1 + '0'
_bcd3:  inc     r18
        subi    r16, low(100)           ;-100
        sbci    r17, high(100)
        brcc    _bcd3

        ldi     r17, 10 + '0'
_bcd4:  dec     r17
        subi    r16, -10                ;+10
        brcs    _bcd4

        subi    r16, -'0'
        ret
;-------------------------------------------------------------------------


Peter

Autor: dds5 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Philipp
AVR-Asm kenn ich leider nicht, hab bisher nur mit (in dieser
Reihenfolge) Z80, µPD75108 (4Bit!), 8051, PIC16C und jetzt PIC18F
gearbeitet. Vieles kann man trotzdem erkennen und teilweise auch
verstehen, aber ist schon blöd dass jeder andere Mnemonics benutzt weil
fast alle Markenschutz haben.
Wette verlier ich wahrscheinlich, weil
1. Ergebnis liegt nicht in ASCII sondern 3 Byte gepackt BCD vor.
2. Es ist nur mit den Standard AppNote Routinen verglichen.



@Peter
Interessante Technik, alternierendes addieren / subtrahieren.
Das sieht wirklich nicht mehr unterbietbar aus.
Den Tippfehler in Zeile 22 bügelt der Profi selbst aus und verliert
kein Wort darüber (bin halt kein Profi), aber welchen numerischen Wert
hat der Ausdruck in Z 45 "-'0'" oder ist da nur das "-" zu viel?

Dieter

Autor: Philipp Sªsse (philipp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, mit dem abwechselnden Addieren spart man sich noch jeweils das
zurücknehmen der überschüssigen Subtraktion: noch drei Befehle gespart.
Clever!

Das -'0' ist richtig, entspricht dem -100 in meinem Code, ist aber
nur verständlich, wenn man AVR-Assembler kennt: es gibt kein 'ADDI',
also 1-Byte-Konstantenaddition, sondern nur SUBI. Um '0' zu addieren,
muß man also -'0' subtrahieren. (Verstehen tue ich das Fehlen von ADDI
übrigens nicht, schließlich braucht man keinen eigenen Befehl im µC,
sondern nur eine Übersetzung durch den Assembler.)

Autor: Patrick M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C würde ich einfach itoa() aus der stdlib benutzen.

Grüße

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.