PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Externen Interrupt, wenn er eintritt, deaktivieren



Bääääär
09.08.2009, 18:57
Hallo!

Ich habe mir grade die Funktion der ASURO-Taster für meine Programme klauen wollen, da ich genau sowas brauche. Dabei wird, nachdem eine Taste gedrückt wurde und ein Interrupt an INT0 eingetreten ist, der Interruptpin in der ISR für die Messung als Ausgang benutzt. Das jedoch löst einen weiteren Interrupt aus, welcher nach abschluss der ISR ein tritt und seinseseits wieder einen Interrupt auslöst usw.
Ich wollte das unterbrechen, indem ich am Beginn der ISR per GICR &= ~(1 << INT0); den Interrupt deaktiviere und ihn mit GICR |= (1 << INT0); am Ende des Interrupts wieder aktiviere. Er ist dann also in der Zeit, in der die Messungen geschehen ausgeschaltet.
Soweitdie Theorie. In der Praxis löst das nach LOW zeihen des Pins während der Messung dennoch einen Interrupt aus.

Was kann ich tun?
Bääääär

sternst
09.08.2009, 19:12
Weil auch bei deaktivierten Interrupt das Ereignis-Flag gesetzt wird. Dieses musst du vor dem Ende der ISR löschen. Das Deaktivieren des Interrupts kannst dir dann auch sparen.

Besserwessi
09.08.2009, 19:12
Wenn die Taste Prellt kann mehr als ein Interrupt ausgelöst werden. Es könnte helfen das Interrupt Flag register zu löschen. Es könnte auch nötog sein dsa Flag nach dem GICR |= (1 << INT0) noch mal zu löschen.

Es kommt auch darauf an was für ein Interrupt gewählt wurde, ob als LEvel oder als Flanken gesteuerter Interrupt. Das Steht in MCUCR.

Bääääär
09.08.2009, 19:36
Ja, das mit dem Flag hatte ich versucht. Im Datenblatt steht, man solle eine 1 draufschreiben, um es zu löschen. Also hab ich die Deaktivierung des Interrupts weggelassen und nur am Ende der ISR ein GIFR |= (1 << INTF0); aufgerufen. Allerdings wird danach nie wieder ein Interrupt ausgeführt... Selbst ein Reaktivieren nach dem Flag-löschen durch GICR |= (1 << INT0) brachte da nichts.
Als Interrupt hatte ich Flankengesteuert gewählt - also eine ISR bei fallender Flanke.

Bääääär

PS: Prellen sollte kein Problem sein, das ist erstmal egal. Fackt war, dass die ISR nach dem ersten Tastendruck unaufhörlich lief. Egal, ob man einen Taster berührte oder nicht...

Bääääär
10.08.2009, 16:40
Hallo nochmal!

Im ATMega32-Datanblatt steht folgendes:

When changing the ISC2 bit, an interrupt can occur. Therefore, it is recommended
to first disable INT2 by clearing its Interrupt Enable bit in the GICR Register. Then,
the ISC2 bit can be changed. Finally, the INT2 Interrupt Flag should be cleared by writing a logical
one to its Interrupt Flag bit (INTF2) in the GIFR Register before the interrupt is re-enabled.

Draus schließe ich, dass - unabhängig davon, dass es hier einen anderen Interrupt betrifft und es um das Ändern einer Interrupt-Einstellung geht - erst der Interrupt deaktiviert und dann das Flag gelöscht werden muss. Danach erst soll die ISR wieder aktiviert werden.
Also hab ich jetzt am Beginn das Löschen des INT0 Bits im GICR-Register, dann die Messung und danch das Löschen des Flags mit anschließender Reaktivierung der ISR. Leider ändert sich nichts. Das Löschen des Flags stoppt die weitere Ausführung der ISR.

Das, was hier steht, geht bei mir so nicht:
Bit 6 – INTF0: External Interrupt Flag 0
When an edge or logic change on the INT0 pin triggers an interrupt request, INTF0 becomes set
(one). If the I-bit in SREG and the INT0 bit in GICR are set (one), the MCU will jump to the corresponding
interrupt vector. The flag is cleared when the interrupt routine is executed.
Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared
when INT0 is configured as a level interrupt.
Das setzten des INTF0-Bits stoppt wie gesagt jegliche weitere Ausführung. Und als "Level interrupt" hab ich's ja nicht konfiguriert...

Bääääär

Besserwessi
10.08.2009, 20:56
Das Löschen des Interrupt-flags sollte nur die eine noch ausstehende Ausführung des Interrupts verhindern. Wenn der Interrupt als fallende Flanke eingestellt ist, muß aber auch dafür gesorgt werden, das der Pin zwischenzeitlich auch wieder auf High geht.

Sonst einfach man den Code zeigen, das sollte das Ratespiel verkürzen.