Forum: Mikrocontroller und Digitale Elektronik sprungbefehler mit 8051


von Daniel (Gast)


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!
1
    mov     A,wert
2
    cjne    A,#01h,carry_check
3
    inc     A
4
    jmp     springen
5
carry_check:
6
    jc      springen
7
                         
8
9
multiplizieren:
10
    clr     cy
11
    mul     AB                      ;multipliziere den Inhalt von A Register mit B Register
12
    jnb     OV,Temperaturueberwachung
13
 
14
15
springen:
16
    mov     dptr,#Marke1            
17
    jmp     @A+dptr  
18
               
19
Marke1:
20
jmp     Programm1
21
Marke2:
22
jmp     Programm2
23
Marke3:
24
jmp     Programm3
25
Marke4:
26
jmp     Programm4
27
Marke5:
28
jmp     Programm5
29
Marke6:
30
jmp     Programm6

freundliche Grüße
Daniel

von JW (Gast)


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

von MaWin (Gast)


Lesenswert?

Hint:
Wie gross ist ( #Marke2 - #Marke1 ) ?

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

von Martin (Gast)


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.

von Daniel (Gast)


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?
1
    mov     A,wert
2
    cjne    A,#01h,addition
3
    jmp     Sprungverteiler
4
addition:
5
    mov     A,wert
6
    add     A,@R0         ;R0 zeigt auf wert
7
8
Sprungverteiler:
9
    mov     dptr,#Marke1
10
    jmp     @A+dptr      ; genauer JMP @(2*wert)+DPTR
11
12
Marke1:
13
jmp     Programm1
14
Marke2:
15
jmp     Programm2
16
Marke3:
17
jmp     Programm3
18
Marke4:
19
jmp     Programm4
20
Marke5:
21
jmp     Programm5
22
Marke6:
23
jmp     Programm6

von Martin (Gast)


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

von Daniel (Gast)


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.
1
multiplizieren:
2
    mov     B,#02h
3
    mov     A,wert
4
    clr     cy
5
    mul     AB 
6
    mov     dptr,#Mahlen
7
    jmp     @A+dptr     
8
;............    
9
;..........

MfG
Daniel

von Kai Klaas (Gast)


Lesenswert?

Dein Code ist Murks!

Schau mal hier (Seite 9, rechts unten):

http://www.nxp.com/acrobat_download2/various/80C51_FAM_ARCH_1.pdf

Kai Klaas

von Daniel (Gast)


Lesenswert?

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

Gruß Daniel

von Peter D. (peda)


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.
1
; Input: A = Index (0..255)
2
jump_to_program:
3
        cjne    a, #(tab_end - tab_start) / 2, _jtb1    ; error check
4
_jtb1:  jnc     error
5
        mov     dptr, #tab_start
6
        add     a, acc                  ; * 2
7
        jnc     _jtb2
8
        inc     dptr                    ; handle carry
9
_jtb2:  mov     r7, a
10
        movc    a, @a+dptr              ; get high byte
11
        xch     a, r7
12
        inc     a
13
        movc    a, @a+dptr              ; get low byte
14
        mov     dph, r7
15
        mov     dpl, #0
16
        jmp     @a+dptr
17
18
error:                                  ; error handler: index out of table
19
        ret
20
21
tab_start:
22
        dw      pr1, pr2, pr3, pr4
23
tab_end:
24
25
pr1:    ret
26
pr2:    ret
27
pr3:    ret
28
pr4:    ret


Peter

von R. W. (quakeman)


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

von Peter D. (peda)


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

von R. W. (quakeman)


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

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.