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.
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
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.
MfG
Stefan
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.
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...
Hallo nochmal!
Im ATMega32-Datanblatt steht folgendes:
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.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.
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:Das setzten des INTF0-Bits stoppt wie gesagt jegliche weitere Ausführung. Und als "Level interrupt" hab ich's ja nicht konfiguriert...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.
Bääääär
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.
Lesezeichen