www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik sprungbefehler mit 8051


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,

bei diesem Programmausschnitt funktioniert etwas nicht so, wie es sein 
soll. Wenn der Wert 00h im speicherplatz wert steht, soll zur Marke1 
gesprungen werden. Dies funktioniert auch. Ebenfalls funktioniert ein 
Sprung zur Marke2, wenn 01h im Speicher wert steht. Die weiteren Sprünge 
also mit 03h, 04h, ... funktionieren einfach nicht. Für Hilfe bin ich 
Euch dankbar!
    mov     A,wert
    cjne    A,#01h,carry_check
    inc     A
    jmp     springen
carry_check:
    jc      springen
                         

multiplizieren:
    clr     cy
    mul     AB                      ;multipliziere den Inhalt von A Register mit B Register
    jnb     OV,Temperaturueberwachung
 

springen:
    mov     dptr,#Marke1            
    jmp     @A+dptr  
               
Marke1:
jmp     Programm1
Marke2:
jmp     Programm2
Marke3:
jmp     Programm3
Marke4:
jmp     Programm4
Marke5:
jmp     Programm5
Marke6:
jmp     Programm6

freundliche Grüße
Daniel

Autor: JW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Daniel,
soweit ich mich noch an 8051 erinnern kann sind die "JMP xyz"'s doch 2 
Byte lang.

    mov     A,wert
    add     A,A          ; falls das so einfach geht
    mov     dptr,#Marke1
    jmp     @A+dptr      ; genauer JMP @(2*wert)+DPTR

Marke1:
jmp     Programm1
Marke2:
jmp     Programm2
Marke3:
jmp     Programm3
Marke4:
jmp     Programm4
Marke5:
jmp     Programm5
Marke6:

So könnte es besser gehen ;-)

Gruß,
Jürgen

Autor: MaWin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hint:
Wie gross ist ( #Marke2 - #Marke1 ) ?

(Danach kann man erklären, warum es mit Marke2 doch geht)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Je nachdem, ob der JMP-Befehl in eine 2- oder 3-Byte Folge übersetzt 
wird, muß der Wert im Akku verdoppelt oder verdreifacht werden.

Beispiel (2-Byte JMP = AJMP):

Akku = 0 verzweigt zur Marke1
Akku = 2 verzweigt zur Marke2
Akku = 4 verzweigt zur Marke3

usw. und entsprechend für 3-Byte JMP-Befehl LJMP.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die verschiedenen Marken  liegen ziemlich sicher nicht über 0ffh wenn du 
das meinst, MaWin? Ich habe es nun so ähnlich probiert, wie Jürgen es 
meinte, jedoch ohne Erfolg. Liegt es vielleicht doch daran, dass man bei 
der Addition von Akku und dptr etwas berücksichtigen muss?
    mov     A,wert
    cjne    A,#01h,addition
    jmp     Sprungverteiler
addition:
    mov     A,wert
    add     A,@R0         ;R0 zeigt auf wert

Sprungverteiler:
    mov     dptr,#Marke1
    jmp     @A+dptr      ; genauer JMP @(2*wert)+DPTR

Marke1:
jmp     Programm1
Marke2:
jmp     Programm2
Marke3:
jmp     Programm3
Marke4:
jmp     Programm4
Marke5:
jmp     Programm5
Marke6:
jmp     Programm6

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> soweit ich mich noch an 8051 erinnern kann sind die "JMP xyz"'s
>> doch 2 Byte lang.

JMP wird entweder in AJMP (2 Bytes, Verzweigungen innerhalb des gleichen 
2-KBytes Blocks) oder in LJMP (3 Bytes, Verzweigungen im gesamter 
Adressraum) übersetzt
(siehe Beitrag "Re: sprungbefehler mit 8051").

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, vielen Dank schon mal!
wie ich es nun programmieren muss, habe ich nun verstanden
mit null und eins funktioniert es schon, jedoch habe ich noch probleme 
bei der multiplikation mit 02h. ich habe das leider noch nie gemacht. 
Der inhalt von A und B - Register(2) soll multipliziert werden und im 
LSB und dem nächsthöherem bit aufscheinen. Es handelt sich nur um kleine 
werte.
multiplizieren:
    mov     B,#02h
    mov     A,wert
    clr     cy
    mul     AB 
    mov     dptr,#Mahlen
    jmp     @A+dptr     
;............    
;..........        

MfG
Daniel

Autor: Kai Klaas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Code ist Murks!

Schau mal hier (Seite 9, rechts unten):

http://www.nxp.com/acrobat_download2/various/80C51...

Kai Klaas

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
besten DANK an euch!
es hat gaklappt. Vor allem die letzte Antwort mit dem Datenblatt war 
sehr hilfreich.

Gruß Daniel

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einen andere Möglichkeit ist, die Sprungadresse aus der Tabelle zu 
lesen.
Du solltest auch einen Test vornehmen, ob überhaupt ein Sprungziel da 
ist. Sonst springst Du ins Nirwana und wunderst Dich, was Dein Programm 
macht.
; Input: A = Index (0..255)
jump_to_program:
        cjne    a, #(tab_end - tab_start) / 2, _jtb1    ; error check
_jtb1:  jnc     error
        mov     dptr, #tab_start
        add     a, acc                  ; * 2
        jnc     _jtb2
        inc     dptr                    ; handle carry
_jtb2:  mov     r7, a
        movc    a, @a+dptr              ; get high byte
        xch     a, r7
        inc     a
        movc    a, @a+dptr              ; get low byte
        mov     dph, r7
        mov     dpl, #0
        jmp     @a+dptr

error:                                  ; error handler: index out of table
        ret

tab_start:
        dw      pr1, pr2, pr3, pr4
tab_end:

pr1:    ret
pr2:    ret
pr3:    ret
pr4:    ret


Peter

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ein kleiner Hinweis.
Wenn du eine Multiplikation mit 2 vornehmen willlst, dann benutze nicht 
den langsamen MUL Befehl sondern verschiebe die Bits mit dem schnellen 
RL Befehl. Eine Multiplikation des Akku mit 2 entspricht dann "RL A".

Ciao,
     Rainer

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fox Mulder schrieb:
> Eine Multiplikation des Akku mit 2 entspricht dann "RL A".

Dann mußt Du CY aber vorher löschen.
Schneller geht daher "ADD A, ACC".


Peter

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Fox Mulder schrieb:
>> Eine Multiplikation des Akku mit 2 entspricht dann "RL A".
>
> Dann mußt Du CY aber vorher löschen.
> Schneller geht daher "ADD A, ACC".

Das stimmt so nicht ganz.

Ich habe ja explizit den RL Befehl genommen, welcher nicht das Carry Bit 
berücksichtigt im Gegensatz zu RLC.
"RL A" ist ebenfalls wie "ADD A, ACC" ein 1 Machinenzyklus Befehl, aber 
"RL A" benötigt nur ein Byte wohingegen der "ADD A, ACC" 2 Byte 
Speicherplatz benötigt.
Sogesehen sind beide Befehle zwar gleich schnell, aber der RL braucht 
nur 50% des Speichers. ;)

Ciao,
     Rainer

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.