www.mikrocontroller.net

Forum: Codesammlung Taschenrechner

Autor: Markus (Gast)
Datum: 17.06.2008 21:02
Dateianhang: LCDtest.asm (5,7 KB, 60 Downloads) | formatierter Code

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: 17.06.2008 21:31

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: 18.06.2008 10:51

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: 18.06.2008 11:48

Nimm anstelle des ADIW ein

subi     reg,0xd0

dann sollte es passen.

Gruß Jörg
Autor: Besserwisser (Gast)
Datum: 18.06.2008 16:05

@ 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: 18.06.2008 16:19
Dateianhang: dual2bcd.asm (891 Bytes, 54 Downloads) | formatierter Code

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: 18.06.2008 16:20

@Besserwisser: Kein Problem. War ja nett das du so schnell helfen
wolltest! Danke dir!
Autor: Besserwisser (Gast)
Datum: 18.06.2008 19:51

@ 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: 18.06.2008 19:57

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: 18.06.2008 20:01

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: 19.06.2008 08:31

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: 19.06.2008 18:40

@ 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 Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net