-         

Ergebnis 1 bis 6 von 6

Thema: Externen Interrupt, wenn er eintritt, deaktivieren

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.05.2007
    Alter
    26
    Beiträge
    183

    Externen Interrupt, wenn er eintritt, deaktivieren

    Anzeige

    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

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    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

  3. #3
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    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.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.05.2007
    Alter
    26
    Beiträge
    183
    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...

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.05.2007
    Alter
    26
    Beiträge
    183
    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

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    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.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •