mikrocontroller.net

Forum: Projekte & Code Taschenrechner


Autor: Markus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mit dem ATMega16 ein LCD-Display zur aktuellen Ausgabe des 
Zahlenwertes sowie die Ausgabe des ergebnisses zu nutzen.
Das Addieren usw. funktioniert. Nur leider bei der AUsgabe zum DIsplay 
kommt bei Zahlen über 9 nur murx raus. Unten steht meien Variante noch 
als umwandlung, als Anhang mein Hauptprogramm.

VIelleicht kann mir jemand helfen wie man vernünftig dies umwandeln 
kann, dass dort z.B. 10+1=11 steht.

-----Funktionsprogramm
;dual2bcd Umwandlung r16 dual nach dezimal in r17 und r16
dual2bcd: push     r15     ;Hilfsregister retten
      clr     r17       ;Hunderte löschen

dual2bcd1: cpi     r16,100   ;Hunderteprobe
       brlo   dual2bcd2    ;dual<100 fertig
       subi   r16,100    ;dual>=100 abziehen
       inc     r17      ;Hunderte zählen
       rjmp   dual2bcd1  ;bis dual<100

dual2bcd2: clr     r15      ;zehner löschen

dual2bcd3: cpi    r16,10    ;zehner probe
       brlo    dual2bcd4  ;dual<10 fertig
       subi    r16,10    ;dual>=10 abziehen
       inc    r15      ;zehner zählen
       rjmp    dual2bcd3  ;bis dual<10

dual2bcd4: swap    r15      ;r15=zehner 0000
       or    r16,r15    ;r16<-Zehner Einer
       pop    r15      ;Hilfsregister zurück


      subi   r16,-$30    ;in ASCII umwandeln



       ret

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dual2bcd4: swap    r15      ;r15=zehner 0000
       or    r16,r15    ;r16<-Zehner Einer
       [snip]
       subi   r16,-$30    ;in ASCII umwandeln

Na, schau mal im Simulator. Nach dem or hast Du in R16 eine zweistellige 
BCD Zahl. Nehmen wir mal an es sei 11 (also 0x011 oder $11)
Um daraus ein ASCII-Zeichen zu machen müsstest Du die beiden Nibbles 
wieder trennen.

Es wäre also besser die beiden garnicht erst in ein Register zu 
vereinigen.
Ich nehme auch an, das Du die ASCII-Zeichen für die Zahl in der 
Reihenfolge 100er, 10er und 1er ausgeben musst.

        [snip]
        ADIW R17, 0x30
        call lcd_output   ; vorher R17 entsprechend umladen
dual2bcd2:
        [snip]
        ADIW R15, 0x30
        call lcd_output   ; vorher R15 entsprechend umladen
dual2bcd4:
        [snip]           ; swap und or fallen weg
        ADIW R16, 0x30
        call lcd_output  ; vorher R16 entsprechend umladen

Autor: Markus Engelmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

danke für die schnelle Antwort. Da kommt aber invalid Register. Muss man 
bei ADIW nicht irgendwie mit ZH und ZL arbeiten?

Autor: Joerg Wolfram (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm anstelle des ADIW ein

subi     reg,0xd0

dann sollte es passen.

Gruß Jörg

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Markus

>Da kommt aber invalid Register. Muss man
>bei ADIW nicht irgendwie mit ZH und ZL arbeiten?

Ja. Tschuldigung bitte.

Autor: Markus Engelmann (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also gerechnet wird richtig. Wenn man z.B. A=1 und B=10 wird auf dem 
LCD-Display in Oshonsoft folgendes Ausgegeben:
1+0=1

Ebenfalls bei der Eingabe erscheint:
1 (für A)
0 (für B)

In der Registeranzeige kann man sehen, dass dort zum jeweiligen 
Zeitpunkt das richtig drin ist. Denn am Ende steht in r19: die 10 für B 
und in r18: steht die 11 für das Ergebnis den der Wert A wird 
überschrieben.

Somit ist leider immer noch das Problem, dass nicht die Gesamtezahl 
sondern nur die letzte Stelle ausgegeben wird.

Ich habe im Anhang die geänderte Funktionsdatei da der Hauptteil ja 
nicht verändert wurde von mir.

Ich danke euch schon mal für eure Hilfe!

Autor: Markus Engelmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Besserwisser: Kein Problem. War ja nett das du so schnell helfen 
wolltest! Danke dir!

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Markus:

>in r18: steht die 11 für das Ergebnis
Mag sein, aber die Umwandlung arbeitet ja auf R16 und nicht R18

>Somit ist leider immer noch das Problem, dass nicht die Gesamtezahl
>sondern nur die letzte Stelle ausgegeben wird.

Irgendwie hast Du auch was komisches aus meinen Änderungen gemacht:

;dual2bcd Umwandlung r16 dual nach dezimal in r17 und r16
dual2bcd: push     r15     ;Hilfsregister retten
      clr     r17       ;Hunderte löschen

dual2bcd1: cpi     r16,100   ;Hunderteprobe
       brlo   dual2bcd2    ;dual<100 fertig
       subi   r16,100    ;dual>=100 abziehen
       inc     r17      ;Hunderte zählen
       rjmp   dual2bcd1  ;bis dual<100
        subi  R17, 0xd0
        call lcd_output   ; vorher R17 entsprechend umladen
dual2bcd2: clr     r15      ;zehner löschen

dual2bcd3: cpi    r16,10    ;zehner probe
       brlo    dual2bcd4  ;dual<10 fertig
       subi    r16,10    ;dual>=10 abziehen
       inc    r15      ;zehner zählen
       rjmp    dual2bcd3  ;bis dual<10
        subi R15, 0xd0
        call lcd_output   ; vorher R15 entsprechend umladen
dual2bcd4:
      subi   r16,0xd0    ;in ASCII umwandeln
        call lcd_output  ; vorher R16 entsprechend umladen
          pop    r15      ;Hilfsregister zurück

       ret

Wenn Du den output nicht in der subroutine machen willst,
dann musst Du R15 vor dem Aufruf der Umwandlung sichern und nach der 
Umwandlung R17 = Hunderter, R15 = Zehner und R16 = Einer ausgeben.
Nach der Ausgabe kannst Du R15 dann wieder vom Stack holen.

Klar?

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, habe selbst noch einen Fehler gemacht:

;dual2bcd Umwandlung r16 dual nach dezimal in r17 und r16
dual2bcd: push     r15     ;Hilfsregister retten
      clr     r17       ;Hunderte löschen

dual2bcd1: cpi     r16,100   ;Hunderteprobe
       brlo   dual2bcd2    ;dual<100 fertig
       subi   r16,100    ;dual>=100 abziehen
       inc     r17      ;Hunderte zählen
       rjmp   dual2bcd1  ;bis dual<100
dual2bcd2:
        subi  R17, 0xd0
        call lcd_output   ; vorher R17 entsprechend umladen
        clr     r15      ;zehner löschen

dual2bcd3: cpi    r16,10    ;zehner probe
       brlo    dual2bcd4  ;dual<10 fertig
       subi    r16,10    ;dual>=10 abziehen
       inc    r15      ;zehner zählen
       rjmp    dual2bcd3  ;bis dual<10
dual2bcd4:
        subi R15, 0xd0
        call lcd_output   ; vorher R15 entsprechend umladen

      subi   r16,0xd0    ;in ASCII umwandeln
        call lcd_output  ; vorher R16 entsprechend umladen
          pop    r15      ;Hilfsregister zurück

       ret

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht sollte man den Thread mal umhängen.
Kommt mir nicht so vor als hätte er in der Codesammlung was zu suchen.

Autor: Markus Engelmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

bei dual2bcd4:
        subi R15, 0xd0   sagt er an dieser Stelle invalides Register. 
Wenn man dies ausklammert um zu prüfen, ob noch ein Fehler ist, ist die 
Ausgabe

2xLeerfeld 00+2xLeerfeld11=2xLeerfeld111
Wenn A=10 und B=1

Autor: Besserwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Markus
>subi R15, 0xd0   sagt er an dieser Stelle invalides Register.

subi geht nicht mit allen Registern. Das hatte ich in dem Augenblick 
nicht im Kopf aber guck einfach mal in der Befehlsbeschreibung und nimm 
ein anderes Register.

2xLeerfeld 00+2xLeerfeld11=2xLeerfeld111 entspricht "  00  11  111" 
Richtig?

Das lässt sich so aus dem Code nicht ableiten. Das musst Du selber 
wissen, wie das zustandekommt.

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.