Forum: Mikrocontroller und Digitale Elektronik Blinkende LED an 8051


von Mathias D. (pfmd86)


Lesenswert?

Habe meine ersten Erfolge mit dem 8051 zu verzeichnen. Sprünge mit jmp 
und bedingte Sprünge und der Befehl mov sind erkundet. Eine leutende LED 
an sich ist aber langweilig. Wie bekommt man jetzt ein blinken hin??? 
dazu muss ich sicher an den Timer des µC, oder? Kann mir das einer näher 
erklären=

von norad (Gast)


Angehängte Dateien:

Lesenswert?

@Mathias Denzin


>Wie bekommt man jetzt ein blinken hin???
>dazu muss ich sicher an den Timer des µC, oder? Kann mir das einer näher
>erklären=

Ein Timer ist nicht unbedingt nötig, denn mit ner Warteschleife gehts 
auch.

Siehe Anhang!

Aber Warteschleifen haben den Nachteil das der µC auch nichts anderes 
tut als die Warteschleife abzuarbeiten.

Eine bessere Lösung wäre einen Timer zu verwenden der alle 50ms einen 
Ausgang toggelt.

Dann könnte µC auch andere Dinge erledigen.


MFG
norad

von Mathias D. (pfmd86)


Lesenswert?

Also mein Assembler kann damit nix anfangen: soll "0h" die 0 in HEX 
sein??? Ich bekomme es nichtmal simuliert um mir das anzugucken, wie es 
geht...

Warnungen/Fehler:
Zeile 1:5     DelayCounter0           DATA      0h ;>err6: unbekannter 
Befehl bzw. Sprungziel nicht gefunden
Zeile 1:6     DelayCounter1           DATA      1h ;>err6: unbekannter 
Befehl bzw. Sprungziel nicht gefunden
Zeile 1:7     DelayCounter2           DATA      2h ;>err6: unbekannter 
Befehl bzw. Sprungziel nicht gefunden
Zeile 1:10 ORG 0h ;>err11: Adresse liegt in eventuell beschriebenem 
Bereich
Zeile 1:27         PUSH  DelayCounter0 ;>err7: Variable nicht erkannt
Zeile 1:28         PUSH  DelayCounter1 ;>err7: Variable nicht erkannt
Zeile 1:29         MOV   DelayCounter1, #86H ;>err1: ungültige 
Operandenkombination
Zeile 1:31         MOV   DelayCounter0, #29H ;>err1: ungültige 
Operandenkombination
Zeile 1:40         DJNZ  DelayCounter0, ____2_Delay0 ;>err1: ungültige 
Operandenkombination
Zeile 1:41         DJNZ  DelayCounter1, ____1_Delay0 ;>err1: ungültige 
Operandenkombination
Zeile 1:42         POP   DelayCounter1 ;>err7: Variable nicht erkannt
Zeile 1:43         POP   DelayCounter0 ;>err7: Variable nicht erkannt

 45 Zeilen übersetzt. Code Ende bei 002Bh.
 4 Labels:
  Main: 0003h
  Delay0: 000Bh
  ____1_Delay0: 0014h
  ____2_Delay0: 0017h

von Thomas (Gast)


Lesenswert?

Neee, an den Timer musst Du da auch nicht. Kannst Du ebenfalls mit 
Zeitschleife machen (auch genannt: "busy waiting"). Es gibt einen 
asm-Befehl namens "complement bit", müsst in 8051asm "cpl" sein. Damit 
änderst Du den Status des Pins. Also aus 1 wird 0 u.u.

Grütze,

t


pseudocode:

endlos:
cpl led_pin
verzögerung_nach_wahl
ljmp endlos

von Thomas (Gast)


Lesenswert?

argh
Bitte letzten post ignorieren  :)

von lontano (Gast)


Lesenswert?

Augen weit aufmachen: 50 ms ! Turbo Impulse! oder mehrere delays 
hintereinender...fuer den Anfang ;-)

von jack (Gast)


Lesenswert?

>Bitte letzten post ignorieren  :)

Du mußt ja nur ljmp durch sjmp ersetzen.

von Mathias D. (pfmd86)


Lesenswert?

Thomas wrote:

> pseudocode:
>
> endlos:
> cpl led_pin
> verzögerung_nach_wahl
> ljmp endlos

Das mit dem cpl hab ich glaub ich gerallt... Kann ich damit auch 
komplette Ports umdrehen, also bewirkt

mov P0,#10101010b
cpl P0

dann P0 = 01010101 ???

Richtig verstanden???
Aber wir bekomme ich denn die Verzögerung von z.B. 1 Sekunde oder 0,5 
Sekunde hin???

von jack (Gast)


Lesenswert?

Warten:
  djnz R2, Warten
  djnz R3, Warten
  djnz R4, Warten
ret

R4 muß vor Aufruf der Warteschleife auf 20 bis 100 eingestellt werden,
damit das Ganze nicht zu lang wird.

mov R4, #20d
Warten

von jack (Gast)


Lesenswert?

Die Verzögerung kannst Du ja mal zur Übung ausrechnen ;-)

von Sebastian (Gast)


Lesenswert?

JA, cpl invertiert auch komplette Ports.
Die Verzögerung kann durch zwei Zählvariablen und entsprechend auch zwei 
ineinander verschachtelte Schleifen erreicht werden.

Pseudocode: (Ohne Garantie)
mov register1, startwert1
mov register2, startwert2
:schleife2
:schleife1
djnz register1, schleife1;
mov register1, startwert1;
djnz register2, schleife2;

Die Startwerte sind von Null verschiedene Byte-Zahlen. Es wird rückwärts 
gezählt.
Nebenbei gesagt, die Fehler "ungültige Operandenkombination" könnten 
daher kommen, daß Register statt RAM-Variablen verwendet werden müssen.

von Niels H. (monarch35)


Lesenswert?

Mathias Denzin wrote:

> Das mit dem cpl hab ich glaub ich gerallt... Kann ich damit auch
> komplette Ports umdrehen, also bewirkt

Versuchst du gerade Assembler ohne Docu zu lernen? Das geht bestimmt 
nicht gut. Ich würde dir dieses PDF ans Herz legen wollen:

http://www.atmel.com/dyn/resources/prod_documents/doc0509.pdf


> mov P0,#10101010b
> cpl P0
>
> dann P0 = 01010101 ???

Nein, laut Doku kann der 8051 nur den Accu oder eine einzelne Bitadresse 
"complementieren" als invertieren. Oben beschriebender Code dürfte nicht 
das tun, was man erwarten würde, da man mit P0 einen ganzen 8-Port 
adressiert.

Du müsstest also P0 erst in den Accu holen, diesen dan mit "cpl a" 
invertieren und dann den Accu wieder in P0 schreiben, um das zu tun, was 
du möchtest.

Was pausenschleifen betrifft, eigenet sich der DJNZ (Decrement and jump 
on not-zero) Befehl. Bei höheren Taktraten sollten die Warteschleifen 
verschachtelt werden, um Frequenzen zu erzeugen, die innerhalb des 
sichtbaren Bereiches liegen..

von Niels H. (monarch35)


Lesenswert?

Sebastian wrote:
> JA, cpl invertiert auch komplette Ports.

Entweder ist das nicht richtig oder ich hab einen Passus in der 
Assemblerreferenz überlesen...

von Sebastian (Gast)


Lesenswert?

Ach ja, sorry. Daß man einen ganzen Port komplementieren kann, war wohl 
ein Trugschluß.

von Peter D. (peda)


Lesenswert?

Sebastian wrote:
> Ach ja, sorry. Daß man einen ganzen Port komplementieren kann, war wohl
> ein Trugschluß.

Nö, kann man:
1
xrl p0, #0FFh

Peter

von MC (Gast)


Lesenswert?

Man kann einen ganzen Port invertieren, wenn man über den Akku geht:

mov a,p0
cpl a
mov p0,a

(wenn ich mich nicht irre).

von norad (Gast)


Lesenswert?

@Mathias Denzin


>Also mein Assembler kann damit nix anfangen: soll "0h" die 0 in HEX
>sein??? Ich bekomme es nichtmal simuliert um mir das anzugucken, wie es
>geht...


Also bei mir funzts.

Ich kann nur vermuten das Du die Include Datei deines µC vergessen hast 
einzutragen.

Ich hatte es absichtlich weg gelasssen da ich nicht wusste welchen µC 
und Entwicklungsumgebung Du verwendest. Sorry.

mfg
norad

von norad (Gast)


Angehängte Dateien:

Lesenswert?

@Mathias Denzin

    DelayCounter0           DATA      0h    entspricht R0
    DelayCounter1           DATA      1h    entspricht R1
    DelayCounter2           DATA      2h    entspricht R3

Im Anhang habe ich ein Dokument hinterlegt die die Speicherorganisation 
des 8051er aufzeigt. Ich hoffe Du kannst damit was anfangen bzw. mal 
näher
ansehen und dich damit beschäftigen.

Da die Delay0 routine Automatisch erstellt wurde, sieht es auch etwas 
verwirrend aus. Man hätte es auch so machen können.


Delay0:
        PUSH PSW
        MOV  R1, #86H
____1_Delay0:
        MOV  R0, #29H
____2_Delay0:
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        DJNZ  R0, ____2_Delay0
        DJNZ  R1, ____1_Delay0
        POP   PSW
        RET

Da man Register nicht direkt mit dem Namen R0 oder R1
PUSHen und POPen kann, muss man einen Namen vereinbaren.
Z.b.   REG0   DATA  0h  für Register 0  (R0)  siehe Anhang


Jetzt bist Du dran.  ;-)

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.