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