Forum: Mikrocontroller und Digitale Elektronik Assembler-Code


von Hansi (Gast)


Lesenswert?

wer hat oder weiß wie man in assembler einen zweistelligen hexwert in
eine dreistellige dualzahl umwandelt.

!! nicht in C++ sondern Assembler

der verwendete prozessor ist ein Atmel AT89S8252
die Hexzahl kommt von einem Temperaturfühler über I²C
anzusteuern ist ein 16x2 Zeiliges Display (DEM16217)

soweit fünktioniert alles, blos ich weiß nicht wie ich den xx Hex-wert
in drei normalzahlen umwandel und ausgebe.

Beispiel:
Ich erhalte die Hex zahl 5C hex
in bin ist es 0111 1100

Dual soll nun ausgegeben werden 92.

man muss die irgendwie in hunderter, zehner und einer aufteilen und
dann ausgeben, aber wie???

für einen lösungsansatz bedanke ich mich

von Tobi (Gast)


Lesenswert?

selten so viel durcheinander geworfenes gehört. der tempfühler gibt dir
ein binäres signal, kein hexadezimales. diese binärzahl willst du in
dezimalstellen zerlegen und dann ausgeben. hex-zahlen haben in einem uC
nichts verloren.

dieses problem wurde schon sehr sehr oft besprochen: stichworte bcd
dual converter, bcd ausgabe, zahlen lcd ausgabe usw...

von Hansi (Gast)


Lesenswert?

hi tobi,

sorry, aber ich habe nirgends was sinnvolles gefunden.
du verweist immer auf die suchfunktion, aber such mal selber. entweder
ist nichts brauchbares dabei, dondern nur solche beiträge wie dein
voriger, oder es handelt sich um programmierung in C.

übrigens, ich kann meinen wert direkt in hex ausgeben, dann werden die
dementsprechenden zeichen der standart character paletten angezeigt,
oder ich kann einzelne bits rausziehen.

auf dem bord habe ich auch 7segment anzeigen untergebracht, und da wird
mein wert richtig angezeigt.

vielleicht suchst du mal das forum durch und findest für mich irgendwo
nen brauchbaren code, oder wenn du so ein crak bist schreib doch einen
;-)

mfg hansi

von Johannes Raschke (Gast)


Lesenswert?

Hallo, Hansi.

Wieso machst Du denn den Tobi so an? Seine Tips waren schon nicht
unsinnig.
Nach einer Minute suchen (+bcd +wandlung)  habe ich z.B.
http://www.avr-asm-tutorial.net/avr_de/rechnen/konversion.html
gefunden. Der Unterpunkt "Von binär nach ASCII" dürfte für Dich
interessant sein.

von Klaus Leidinger (Gast)


Lesenswert?

Hallo Hansi,

ich habe im Progforum diesen Code gefunden (und den Thread dazu noch
lesen!):
http://www.progforum.com/showthread.php?t=875

Ich denke das sollte tun, was Du brauchst.

Viel Erfolg,
Klaus

von Alexander Niessen (Gast)


Lesenswert?

Mal was selbst geschriebenes zum Thema:

;--------------------------------------------------------------------
.def        binzahl = R16       ; umzuwandelnde Zahl
.def        hdtr    = R20       ; ASCII 100er
.def        zenr    = R19       ; ASCII  10er
.def        einr    = R18       ; ASCII   1er

.def        tmp1    = R17       ; Hilfsregister 1
;--------------------------------------------------------------------

;********************************************************************
;* Funktion: bin2ascii
;* Wandelt eine 8 Bit Binärzahl in 3-stelligen ASCII um.
;*
;* Arbeitsregister: tmp1 (wird gesichert und wiederhergestellt)
;* Eingaberegister: binzahl
;* Ausgaberegister: hdtr, zenr, einr
;*
;* Die Register sind im Hauptprogramm zu definieren.
;* Es sollten Register >= R16 gewählt werden. (wg ORI-Befehl z.B.)
;********************************************************************
bin2ascii:
            push    tmp1            ; Arbeitsregister sichern
            clc
            clr     tmp1
            clr     hdtr
            clr     zenr
            clr     einr

            ; Hunderter erfassen:
            ldi     tmp1, 0x0a      ; von 10 an runter zählen
ascloop1:   subi    binzahl, 100    ; 100 subtrahieren
            brcs    zehner          ; Überlauf eingetreten ?
            inc     hdtr            ; Wenn nein, hdtr eins hochzählen
            dec     tmp1            ; Zähler f die Dezimalstelle -1
            brne    ascloop1        ; Wenn Zähler noch nicht Null mache
weiter

            ; Zehner erfassen:
zehner:     subi    binzahl, -100   ; Das 'zuviel subtrahierte'
wieder addieren
            clc
            ldi     tmp1, 0x0a
ascloop2:   subi    binzahl, 10     ; 10 subtrahieren
            brcs    einer
            inc     zenr
            dec     tmp1
            brne    ascloop2

            ; Einer erfassen:
einer:      subi    binzahl, -10    ; Das 'zuviel subtrahierte'
wieder addieren
            clc
            ldi     tmp1, 0x0a
ascloop3:   subi    binzahl, 1      ; 1 subtrahieren
            brcs    bin2ascend
            inc     einr
            dec     tmp1
            brne    ascloop3

bin2ascend: ori     hdtr, 0b00110000    ; ASCII-Umwandlung
            ori     zenr, 0b00110000
            ori     einr, 0b00110000

            pop     tmp1            ; Arbeitsregister wiederherstellen
            ret
;--------------------------------------------------------------------

Sicher gibt es effizienteren Code ...
Aber ich finde dieser hier eignet sich ganz gut, um die Umwandlung zu
verstehen.

Grüße,
Alex

von Peter D. (peda)


Lesenswert?

@Hansi,

wenn Du mit den Suchergebnissen nicht zufrieden bist, dann mußt Du
schon sagen, was Dir daran nicht gefällt. Man findet nämlich wirklich
ganz schnell sehr viel und vor allem gutes.

Es ist auch nicht schlimm zu sagen, wonach man gesucht hat und sich
dann zeigen zu lassen, wie man besser suchen könnte.

Es ist aber schlimm die Leute anzumotzen, wenn man selber nicht mit
Informationen rausrückt !

Keiner kann in Deinen Kopf sehen.

Und ein Blick in den Befehlssatz wäre natürlich am einfachsten, dann
wüßte man nämlich, daß der 8051 einen Divisionsbefehl hat, um ein Byte
in Dezimalziffern zu zerlegen.


@Alex, Johannes,

der AT89S8252 ist ein 8051 und kein AVR.


Peter

von Andi (Gast)


Lesenswert?

Mit ein bißchen Umstellung geht es sogar sehr effizienter wobei Peter
Danneger alles an Effizienz und Sinn bisher übertroffen hat:

bin2ascii:
            ; Hunderter erfassen:
            ldi     hdtr, -1+'0'    ; von 0 an runter zählen
ascloop1:   inc     hdtr            ; Wenn nein, hdtr eins hochzählen
            subi    binzahl, 100    ; 100 subtrahieren
            brcc    ascloop1        ; Überlauf eingetreten ?
            subi    binzahl, -100   ; Das 'zuviel addieren'

            ; Zehner erfassen:
            ldi     zenr, -1+'0'
ascloop2:   inc     zenr
            subi    binzahl, 10     ; 10 subtrahieren
            brcc    ascloop2
            subi    binzahl, -10    ; Das 'zuviel addieren'

            ; Einer erfassen:
einer:      mov     einr, binzahl
            subi     einr,-'0'

            ret

Allerdings sucht Hansi nix für nen AVR sondern für nen 8051 mit dem ich
momentan leider auch nix zu tun habe.
Vielleicht kann Hansi das für seinen 8051 entsprechend umschreiben was
ja kein Problem sein sollte.

Gruß
Andi

von Alexander Niessen (Gast)


Lesenswert?

Stimmt: Für den 8051. Da hab' ich wohl was überlesen. Sorry.

Grüße,
Alex

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.