Forum: Mikrocontroller und Digitale Elektronik Anfänger braucht Hilfe bei AT89C5131 - Interrupts in Assembler


von Klaus X. (blacky27)


Lesenswert?

Hallo,
ich bin noch sehr neu in der Materie und hoffe, dass meine Frage deshalb 
nicht allzu "sinnlos" ist.
In der Schule programmieren wir gerade verschiedene Interrupts 
(Unterbrechung, Timer).
Wir haben jetzt ein Programm geschrieben, bei dem pro Tastendruck eine 
LED leuchtet und automatisch immer um eine Stufe nach links rückt. 
Soweit so gut.
Ich habe das jetzt auf meinem Board (USB-Flashboard von ELektor) 
getestet. Die Schaltung funktioniert, allerdings leuchten alle LEDs auf, 
bis auf eine. Und diese eine "nichtleuchtende LED" verschiebt sich mit 
jedem Tastendruck nach links. Es bewegt sich quasi ein "Loch". Es gibt 
doch sicher eine Möglichkeit, damit nur eine LED leuchtet, und diese 
sich nach links verschiebt.

Das zweite Problem:
Wie kann ich dem Controller mitteilen, dass die LEDs nach erreichen der 
linken Seite, wieder automatisch nach rechts laufen.
Mein Gedankengang >> es muss irgendwas mit dem carry flag zu tun haben.
Wenn das cf=0 dann laufe nach links, wenn cf=1 dann laufe nach rechts.
Klingt einfach, aber.......

Mein Programm sieht folgendermaßen aus:

----------------------------
code_s  segment code
        cseg at 0000h
        ljmpf main

        org 0003h
        ljmp ExInt0

        org 0100h
        rseg code_s

main:   mov A,#128
        setb IT0
        setb EX0
        setb EA

loop:   sjmp loop

ExInt0: rl A
        mov P0,A
        reti

end
------------------------------

Für Hilfe wäre ich sehr dankbar!!!

MfG
Blacky27

von Peter D. (peda)


Lesenswert?

Klaus Xx schrieb:
> Es gibt
> doch sicher eine Möglichkeit, damit nur eine LED leuchtet, und diese
> sich nach links verschiebt.

Ja.
Beim Initialisieren darauf achten, daß die LEDs low-aktiv sind.

Der 8051 schaltet beim Reset alle Pins auf high. Damit nun nicht alle 
Lasten angehen, schaltet man sie üblicher Weise low-aktiv (0 = an).


Peter

von Klaus X. (blacky27)


Lesenswert?

Und wie macht man sowas in Assembler?
Ich kenne mich nur mit den Befehlen aus, die wir bisher benutzt haben.
Falls es da irgendwelche "Tricks" gibt, kenne ich die natürlich nicht.

MfG
Blacky27

von Oliver J. (skriptkiddy)


Lesenswert?

Klaus Xx schrieb:
> Und wie macht man sowas in Assembler?

Man könnte den Wert im Akumulator invertieren, bevor er auf P0 
ausgegeben wird und anschließend noch einmal invertieren.
1
  CPL A   ;invertiert den Inhalt des Akkumulators
2
  MOV P0,A
3
  CPL A

von Peter D. (peda)


Lesenswert?

Klaus Xx schrieb:
> main:   mov A,#128

main:   mov A, #01111111b


Peter

von Klaus X. (blacky27)


Lesenswert?

Danke für die Hilfe!
Ich war auf dem richtigen Weg, aber falsch angewendet.
Ich habe "cpl P0,A" versucht.
KEIL brachte aber ständig eine Fehlermeldung.

Jetzt muss ich mir nur noch einen Kopf zu meinem zweiten Problem machen.


MfG
Blacky27

von AT89C5131-user (Gast)


Lesenswert?

Peter Dannegger hat das Problem gelöst.

>        ljmpf main ?
         ljmp main

von Oliver J. (skriptkiddy)


Lesenswert?

Klaus Xx schrieb:
> Wenn das cf=0 dann laufe nach links, wenn cf=1 dann laufe nach rechts.

Das Carryflag wir nur gesetzt, wenn eine 1 herausgeschoben wird. Da du 
in deinem Fall binär gesehen nur eine 1 im Akkumulator drin hast, wird 
das CF nur gesetzt, wenn du beim Shiften die 1 rechts oder links 
herausschiebst. Das könnte man als Indikator für einen Richtungswechsel 
nutzen.

EDIT:
Allerdings müsstest du dann mit RLC und RRC shiften.

von Klaus X. (blacky27)


Lesenswert?

Das mache ich doch mit dem Befehl "rl A".
Damit schiebe ich doch den Wert von Bit 1 über Bit 2 bis nach Bit 8.
Nach Bit 8 wird dann das carry flag gesetzt. Oder habe ich da im 
Unterricht was falsch verstanden?
Ich weiß nur nicht, wie ich das carry flag überprüfe. Irgendwo muss ich 
dem Controller ja mitteilen, wenn cf=1 >> rr A, bzw. cf=0 >> rl A.

MfG
Blacky27

von Klaus X. (blacky27)


Lesenswert?

AT89C5131-user schrieb:
> Peter Dannegger hat das Problem gelöst.
>
>>        ljmpf main ?
>          ljmp main

Schreibfehler!!!

von Peter D. (peda)


Lesenswert?

Kann man mit dem Carry-Flag machen:
1
ExInt0:
2
        jnc     _m1        ; CY = 0: nach rechts
3
        rl      a          ; nach links
4
        anl     c, acc.7   ; CY = 0 wenn ACC.7 = 0
5
        sjmp    _m2
6
_m1:    rr      a          ; nach rechts
7
        orl     c, /acc.0  ; CY = 1 wenn ACC.0 = 0
8
_m2:    mov     p0, a
9
        reti


Peter

von AT89C5131-user (Gast)


Lesenswert?

hallo Klaus

RL A beeinflusst das carry-bit nicht

von Oliver J. (skriptkiddy)


Lesenswert?

Klaus Xx schrieb:
> Das mache ich doch mit dem Befehl "rl A".
> Damit schiebe ich doch den Wert von Bit 1 über Bit 2 bis nach Bit 8.
> Nach Bit 8 wird dann das carry flag gesetzt. Oder habe ich da im
> Unterricht was falsch verstanden?


Das carryflag dürfte nicht verändert werden, wenn du mit rl und rr 
schiebst.

Schau mal im Instuction-Set nach:
http://www.win.tue.nl/~aeb/comp/8051/set8051.html#51rl

Gruß Skriptkiddy

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.