Forum: Mikrocontroller und Digitale Elektronik AT89C51ED2 Assembler Problem mit Timerflag


von test1234 (Gast)


Lesenswert?

Hallo,

ich arbeite mich gerade in das Thema MC ein und wollte hier nun ein 
erstmal ein paar LED´s zum Blinken bringen.
In meiner Quelltext-C-Version funktioniert das ganze auch, nur scheine 
ich einen Fehler in meinem Assemblercode zu machen.

Das Problem scheint zu sein, das das Flag TF0 nie gesetzt wird, deshalb 
hängt er unten in der schleife "JNB TF0, loop1" fest.

Kann mir jemand weiterhelfen, warum das Flag trotz Überlauf nicht 
gesetzt wird?

hier mal der ganze Code:

$NOMOD51              ;vordefinierten Registersatz deaktivieren
$include(at89c51xd2.inc)               ;Registerdefinitionen für 
80c51ed2

USING 0                           ;Registerbank 0 nutzen
ORG 0000h                          ;bei Reset Sprung zu Hauptprogramm
MOV SP,#0A0h                      ;Stack festlegen
LJMP main
ORG 0100h                         ;Hauptprogramm ab 100h
;---------Hauptprogramm-----------------------------------------
main:
  MOV TMOD,#01h
  SETB EA
  SETB ET0                ;Flag Überlauf Timer 0 ein

  MOV P1,#00h    ;LED an
  CALL delay    ;Unterprogramm delay starten
  MOV P1,#0ffh    ;LED aus
  CALL delay    ;Unterprogramm delay starten

  SJMP main    ;Endlosschleife main

;--Unterprogramm delay----------------

delay:
  CLR TR0
  MOV TH0,#03Ch    ;höherwertiges Timerbyte
  MOV TL0,#0B0h          ;niederwertiges Timerbyte
  MOV R1,#03h
  SETB TR0
  SJMP loop
loop:
loop1:
        JNB TF0, loop1
  CLR TF0
  DJNZ R1,delay
  CLR TR0
RET

;---------ENDE----------------------------------------------
END

Vielen Dank schonmal vorweg für eure Hilfe!

von Thomas (Gast)


Lesenswert?

und wo ist der code für den Timer Interrupt? Du schaltest die Interupts 
ein, ich sehe aber keine Interruptroutine.

Thomas

von test1234 (Gast)


Lesenswert?

Ja, das ist richtig.
Mir ist bewusst, dass ich das Problem auch mittels Interrupts lösen 
könnte. Das wäre allerdings meine nächste Aufgabe.

Daher setze ich das Flag ja eigentlich auch von Hand zurück(in einer ISR 
würde das ja (afaik) von alleine geschehen.

In dem Programm habe ich eigentlich nur vor das Flag abzufragen, aber 
keine richtige ISR zu starten.


Müsste denn nicht trotzdem das Flag bei einem Überlauf gesetzt werden?

LG

von Peter D. (peda)


Lesenswert?

test1234 schrieb:
> In dem Programm habe ich eigentlich nur vor das Flag abzufragen, aber
> keine richtige ISR zu starten.

Und warum tust Du es dann (SETB ET0)?

Dem MC ist es schnuppe, ob Du einen Handler schreibst.
Sobald Du den Interrupt enablest, springt er dorthin, wo der Handler 
stehen sollte.

Willst Du pollen, darfst Du ET0 nicht setzten!


Peter

von Andy A. (crusty)


Lesenswert?

Servus,

das geht auch ohne Interrupt.Du brauchst dann auch oben deinen Timer 
Interrupt gar nicht einschalten.

Das JNB TF0,loop1 frägt da das Überlauf Flag ab, anstelle eines 
Interrupts.

Ein Problem was ich grad sehe ist, das du R1 immer wieder auf 3 setzt 
somit kann er auch nie fertig werden, bzw anders ausgedrückt R1 kann nie 
0 werden und somit kommst du auch schon mal nicht mehr aus der delay 
Routine raus.
Du musst R1 also nur am Anfang einmal auf 03h setzen.
Das zweite ist, wenn du keine Interrupts benutzt dann schalte Sie auch 
nicht ein.
Das dritte wäre, das du auch ein bisschen ans einrücken des Codes 
denkst, somit ist es auch für mich bzw. für andere leichter deinen Code 
zu lesen.

Sollte dann so aussehen:

main:
     MOV TMOD,#01h
blink:
     MOV P1,#00h    ;LED an
     CALL delay    ;Unterprogramm delay starten
     MOV P1,#0ffh    ;LED aus
     CALL delay    ;Unterprogramm delay starten

     SJMP blink    ;Endlosschleife main

delay:
       MOV R1,#03h
delay1:
       CLR TR0
       MOV TH0,#3Ch    ;höherwertiges Timerbyte
       MOV TL0,#0B0h          ;niederwertiges Timerbyte
       SETB TR0

loop1:  JNB TF0, loop1
        CLR TF0
        DJNZ R1,delay1
        CLR TR0
RET

von Andy A. (crusty)


Lesenswert?

Wäre schön wenn du uns verraten würdest ob jetzt alles funktioniert :-)

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.