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
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
Hey, danke für die schnelle Antwort. Da kommt aber invalid Register. Muss man bei ADIW nicht irgendwie mit ZH und ZL arbeiten?
@ Markus >Da kommt aber invalid Register. Muss man >bei ADIW nicht irgendwie mit ZH und ZL arbeiten? Ja. Tschuldigung bitte.
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!
@Besserwisser: Kein Problem. War ja nett das du so schnell helfen wolltest! Danke dir!
@ 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?
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
Vielleicht sollte man den Thread mal umhängen. Kommt mir nicht so vor als hätte er in der Codesammlung was zu suchen.
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
@ 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.
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.