Hallo microcontrollerforum, ich versuche den Wert eines Registers dreistellig darzustellen. Dazu habe ich folgenden Code geschrieben: datenwandeln: ;Eingaberegister=Daten wird in 3 Stellen zerlegt clr Hunderter clr Zehner clr Einer cln ;Negativ Flag Löschen s100: ;Hunderter Stelle ermitteln push daten ;daten auf den Stack retten subi daten,100 ;Von Daten 100 abziehen brmi neg100 ;ist das Ergebniss negativ dann springe nach neg100 inc Hunderter ;erhöhe die Hunderter um 1 pop dummi ;Stack in Dummi Laden da Daten nicht negativ rjmp s100 ;weiterer Durchgang neg100: ;Sind Daten negativ dann pop daten ;letztes positive Ergebnis wiederherstellen s10: ;Zehner Stelle ermitteln push daten ;daten auf den Stack retten subi daten,10 ;Von Daten 100 abziehen brmi neg10 ;ist das Ergebniss negativ dann springe nach neg100 inc Zehner ;erhöhe die Zehner um 1 pop dummi ;Stack in Dummi Laden da Daten nicht negativ rjmp s10 ;weiterer Durchgang neg10: ;Sind Daten negativ dann pop daten ;letztes positive Ergebnis wiederherstellen mov Einer,daten ;der Rest müsten die Einer sein ;ausgabe an lcd leider zeigt es sich das dieser Code nur bis einem Wert von 227 dezimal richtig funktioniert. Könnte mir jemand meinen Fehler aufzeigen? mfg T.Mohrs
@ Thomas Mohrs (Gast) >ich versuche den Wert eines Registers dreistellig darzustellen. Dazu >habe ich folgenden Code geschrieben: Das ist totaler Kauderwelsch, vor allem das wilde pushen und popen. Machs ordentlich wie hier. AVR-Tutorial: ADC MFG Falk
>dieser Code nur bis einem Wert von 227 dezimal richtig funktioniert.
Nein, ich hab keine Ahnung, wieso.
Aber ein Tipp: Es gibt eine simple Möglichkeit, wie Du ohne die x-fache
Anwendung von push und pop auskommen kannst. Addiere doch einfach nach
dem positiven brmi-Test wieder 100 bzw. 10 dazu.
(Und noch einer: Einrückungen verbessern die Lesbarkeit eines Codes
ungemein)
1 | s100: ;Hunderter Stelle ermitteln |
2 | push daten ;daten auf den Stack retten |
3 | subi daten,100 ;Von Daten 100 abziehen |
4 | brmi neg100 ;ist das Ergebniss negativ dann springe... |
5 | inc Hunderter ;erhöhe die Hunderter um 1 |
6 | pop dummi ;Stack in Dummi Laden da Daten nicht negativ |
7 | rjmp s100 ;weiterer Durchgang |
8 | neg100: ;Sind Daten negativ dann |
9 | pop daten ;letztes positive Ergebnis wiederherstellen |
10 | ... |
Alternativ (ohne pop, push und dummi):
1 | s100: ;Hunderter Stelle ermitteln |
2 | subi daten,100 ;Von Daten 100 abziehen |
3 | brmi neg100 ;ist das Ergebniss negativ dann springe... |
4 | inc Hunderter ;erhöhe die Hunderter um 1 |
5 | rjmp s100 ;weiterer Durchgang |
6 | neg100: ;Sind Daten negativ dann |
7 | subi daten, -100 |
8 | ... |
Das 'subi daten, -100' funktioniert einwandfrei.
Vielen Dank für eure guten Hinweise habe das verwerfliche pushen und poppen durch das geniale subtrahieren einer negativen Zahl esetzt und auch einrückungen eingefügt doch trotzdem zeigt mir das Lcd oder ein LED nur Zahlen bis 227 an danacH folgt 00 , ...,00!,00$ usw.bis 00*. Sende ich den Registerinhalt von Data über die serielle Schnittstelle an Hypertext zeigt es mir die entsprechenden ASCI Zeichen bis 255 korrekt an . Wo liegt wohl das Problem ? datenwandeln: ;Eingaberegister=Daten wird in 3 Stellen zerlegt clr Hunderter clr Zehner clr Einer cln ;Negativ Flag Löschen s100: ;Hunderter Stelle ermitteln subi daten,100 ;Von Daten 100 abziehen brmi neg100 ;ist das Ergebniss negativ dann springe nach neg100 inc Hunderter ;erhöhe die Hunderter um 1 rjmp s100 ;weiterer Durchgang neg100: ;Sind Daten negativ dann subi daten,-100 ;von Daten -100 abziehen = 100 addieren s10: ;Zehner Stelle ermitteln subi daten,10 ;Von Daten 10 abziehen brmi neg10 ;ist das Ergebniss negativ dann springe nach neg10 inc Zehner ;erhöhe die Zehner um 1 rjmp s10 ;weiterer Durchgang neg10: ;Sind Daten negativ dann subi daten,-10 ;Von Daten -10 abziehen =10 addieren mov Einer,daten ;der Rest müsten die Einer sein ;ausgabe an lcd mfG T.Mohrs
Ich hab leider keine Ahnung von AVR-ASM (nur PIC-ASM) aber wenn die Befehle das machen, was im Kommentar steht sollte es eigentlich richtig sein. Ich habe für den PIC auch mal so eine Routine geschrieben und die hat ähnlich geabrbeitet. Wie rechnest du denn die einzelnen Stellen in ASCII um? Einfach hex. 30 dazu addiert oder irgendwie anders? Sven
230 minus 100 sind 130, binär 0b10000010. brmi arbeitet aber mit vorzeichenbehafteten Zahlen und somit ist die 130 als -126 interpretiert und der Vergleich somit wahr. Nimm einen Test auf das gesetzte carry - brcs
Hallo mueschel dein Hinweis war richtig. Mit der Abfrage des Carry Bits klappt es jetzt richtig. Woher hast du die Information darueber das der BRMI Befehl mit Vorzeichen rechnet? In der Hilfe des AVR Assemblers findet sich darueber kein Hinweis? oder doch? hallo stepp64 wenn ich dezimale Zahlen In ASCI ausgeben Will addiere ich dezimal 48 dazu oder ldi daten,"0"-1 (das geht mit dem AVR Assembler) und dann den wert der Zahl aufaddieren (aus dem AVR Tutorial) datenwandeln: ;Eingaberegister=Daten wird in 3 Stellen zerlegt clr Hunderter clr Zehner clr Einer cln ; Negativ Flag Loeschen s100: ; Hunderter Stelle ermitteln subi daten,100 ; Von Daten 100 abziehen brcs neg100 ; ist das Carry Flag im SReg gesetzt? ; dann springe nach neg100 ; wird gesetzt wenn bei SUBI die Konstante ; groesser als der Absolutwert des Registers ist inc Hunderter ; erhöhe die Hunderter um 1 rjmp s100 ;weiterer Durchgang neg100: ;Sind Daten negativ dann subi daten,-100 ;zu Daten 100 addieren s10: ;Zehner Stelle ermitteln subi daten,10 ;Von Daten 10 abziehen brcs neg10 ;ist das Carry Flag im SReg gesetzt? ;dann springe nach neg10 inc Zehner ;erhoehe die Zehner um 1 rjmp s10 ;weiterer Durchgang neg10: ;Sind Daten negativ dann subi daten,-10 ;Von Daten 10 abziehen mov Einer,daten ;der Rest muessten die Einer sein ;ausgabe an lcd ldi Daten,48 ; Ascii aufbereiten 0=48 add Daten,Hunderter ; Ascii aufbereiten 0=48
Thomas Mohrs wrote: > Hallo mueschel > > dein Hinweis war richtig. Mit der Abfrage des Carry Bits klappt es jetzt > richtig. Woher hast du die Information darueber das der BRMI Befehl mit > Vorzeichen rechnet? In der Hilfe des AVR Assemblers findet sich darueber > kein Hinweis? oder doch? Seite 10... ...
@ Thomas Mohrs (Gast) >richtig. Woher hast du die Information darueber das der BRMI Befehl mit >Vorzeichen rechnet? Aus der Doku der ASM Befehle. AVR-Tutorial: Vergleiche http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf MfG Falk
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.