Forum: Mikrocontroller und Digitale Elektronik Registerdarstellung


von Thomas Mohrs (Gast)


Lesenswert?

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

von rene (Gast)


Lesenswert?

Das Ganze mal im Simulator laufengelassen ?

von Falk B. (falk)


Lesenswert?

@ 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

von AVRFan (Gast)


Lesenswert?

>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.

von Thomas Mohrs (Gast)


Lesenswert?

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

von Sven S. (stepp64) Benutzerseite


Lesenswert?

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

von Jan M. (mueschel)


Lesenswert?

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

von Thomas Mohrs (Gast)


Lesenswert?

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

von Hannes L. (hannes)


Angehängte Dateien:

Lesenswert?

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...

...

von Falk B. (falk)


Lesenswert?

@ 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
Noch kein Account? Hier anmelden.