Forum: Mikrocontroller und Digitale Elektronik 8051 /INT0 wird nur einmal ausgeführt - Blockade im Kopf


von Guido S. (Gast)


Lesenswert?

Hallo!

Nun habe ich mal wieder einen Abend mit meinem Flash-Board (AT89S8252)
verbracht.
Ich habe versucht den INT0 zu benutzen.
Problem die Interruptroutine wird nur einmal durchlaufen. Am Eingang
P3.2 kommt ein Rechtecksignal an. Dieses Signal ist einige
Millisekunden lang. Dieses Signal soll einfach an die Ausgänge P1.1 und
P3.1 weitergereicht werden.
Hier mal mein kurzes Programm:
  ORG  0
  jmp  start
  ORG  3
  jmp  INTEx0
;***********************************************************************
start:  SETB  EX0    ; Ext0 Int erlauben
  SETB  EA    ; alle Interrupts erlauben
abc:  JMP  abc
INTEx0:  CLR  EX0
  MOV  P3.1,C
  MOV  P1.1,C
INTEx01:  MOV  C,P3.2
  JNC  INTEx01
  MOV  P3.1,C
  MOV  P1.1,C
  SETB  EX0    ; Ext0 Int erlauben
  RETI

Wie kann ich erreichen, dass die Interruptroutine jedesmal abläuft,
wenn das Eingangssignal auf Low geht?

Gruß
Guido

von crazy horse (Gast)


Lesenswert?

du betreibst den Int Zustandsgesteuert, das bedeutet, du IE0 per
Software zurücksetzen.
Bei flankengesteuertem Interrupt (IT0=1) geschieht dies automatisch bei
Annahme des Int.
In der ISR EX0 wieder zu setzen, ist unnötig.
Den SP solltest du auch noch setzen, der steht nach Reset auf 0x07,
macht bei deinem Programm zwar (noch) nichts, aber da gehört er nicht
hin (mitten im Registerbereich, RB1).

Hoffentlich alles richtig, ist ein paar Jahre her, meine 8051-Zeit...

von peter dannegger (Gast)


Lesenswert?

Der Interrupt ist low-aktiv, d.h. er wird nur ausgeführt, solange der
Eingang low ist.
Bei high passiert schlichtweg garnichts.

Es gibt natürlich die Möglichkeit noch einen high-aktiven Interrupt zu
nehmen (T0 im Gate-mode).


Peter

von Guido S. (Gast)


Lesenswert?

Danke für die Hilfe. Manchmal ist man einfach blind.
Der Interrupt war OK. Nur das C-Flag, habe ich nie wieder gelöscht.
So funktionierts:

  ORG  0
  jmp  start
  ORG  3
  jmp  INTEx0
;***********************************************************************
start:  SETB  EX0  ; Ext0 Int erlauben
  SETB  EA  ; alle Interrupts erlauben
abc:  JMP  abc
INTEx0:  CLR  P3.1
  CLR  P1.1
INTEx01:  MOV  C,P3.2
  JNC  INTEx01
  SETB  P3.1
  SETB  P1.1
  RETI

Nochmals Danke und Sorry
Guido

von daniel (Gast)


Lesenswert?

Hallo,

@ Peter
ist es auch moeglich das der INT0 auf Flanken reagiert und nicht nur auf 
den Zustand low?

Ich habe am INT0 einen staendigen LowPegel, ein Timer generiert mir ein 
Zeitfenster und wenn nun ein Pegelwechsel von LOW auf High stattfindet 
soll er es sich merken und den INT0 ausschalten. Bei der anderen Flanke 
soll er es ignorieren und warten bis das Zeitfenster sich schliesst, 
Wenn es geschlossen ist soll der INT0 ausgeschaltet werden.

Vielen Dank
Daniel

von Robert W. (rweber)


Lesenswert?

Hallo,

das sollte eigentlich im Datenblatt deines Controllers beschrieben sein.
Aber weil gerade so schönes Wetter ist:

Im Register TCON0, Bit IT0

Interrupt 0 Type Control Bit
Clear to select low level active (level triggered) for external 
interrupt 0 (INT0#).
Set to select falling edge active (edge triggered) for external 
interrupt 0.

Wenn du allerdings auf eine High Flanke triggern willst, dann solltest 
Du dir mal das PCA ansehen.

Gruss,
rweber

von daniel (Gast)


Lesenswert?

Hallo,
hab es mir auch angeschaut und probiert. Das Resultat war jedoch das er 
sich im Dauerinterrupt befindet. Dieser Zustand ist das groesste Problem 
an der ganzen Sache.
Timer 0 und Timer 1 werden schon verwendet und stehen nicht zur 
verfuegung.

Das Programm hat diesen aufbau:
IRQ-Timer0: setzt Kontrolbit und sprungmarke und reti

main: testet Kontrolbit auf 1
      wenn ja dann wird die Sprungmarke abgearbeitet

sprungmarke: setzt neue zeit fuer timer 0 und dann interrupt 0 auf 1 
also
SETB EX0 und dann weg

IRQ-INT0:
 JNB IT0, int0end
 setb merkeflanke
 CLR IT0
 CLR EX0
int0end:
 reti

Das Prinzip fuer das Zeitfenster, die Zeiten, die Operationen und 
sprungmarken funktionieren einwandfrei. Jedoch sobald der INT0 
hinzukommt, ist er im Dauer- Interruptrequest und schliesst das 
Zeitfenster nicht mehr.
Sozusagen, weil am INT0 eine staendige 0, macht er einen staendigen 
Interrupt! ER reagiert also nicht auf Flanken :( !!!! Grosses 
Verhaengnis :(

Aber wenn ich mir das Datenblatt anschaue dann steht jedoch da das er 
edge reaction macht, sollte also auf flanken reagieren.

Vielen Dank
Daniel

von daniel (Gast)


Lesenswert?

Hallo,
PS: wenn die Zeit des Timers0 abgelaufen ist, sieht es so ungefaehr aus:
IRQ-Timer0: setzt kontrollbit und sprungmarke (andere als vorher !) und 
dann
  weg(reti)

main: wie oben gesagt

Sprungmarke: CLR EX0, Zeit vorbei also soll auch der Interrupt 
ausgeschaltet
  werden

Ich weiss das der Int0 lowaktiv ist und mein Pegel am Pin genau 
invertierend arbeitet, also er ist die ganze Zeit auf low und wenn was 
passiert macht er ne Flanke von 0 nach 1 ( Low->High). Ich setzte dabei 
beim Interrupt auf die Flanken reaktion und weiss aber nicht ob der nur 
eine zustandsreaktion besitzt.

Wenn er nur eine Zustandsreaktion besitzt kann ich wohl nur mit dem 
verlegen von Interruptproiritaeten arbeiten. Sozusagen Timer0 hoeher als 
Int0. Ist das beim 8051 Moeglich mit dem IE Register?


Vielen Dank
Daniel

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.