ATtiny2313 ext. Interrupt wird doppelt ausgelöst

OP #3099180
Lesenswert?
• ▲
▼
Hallo,

ich möchte per INT0 eine Tasterentprellung machen. Beim Testen (Taster 
wird ganz schnell mehrfach betätigt) wird meine ISR 2 mal ausgeführt!

Warum?

Mit cli(); sperre ich doch weitere Interrupts und auch wenn ich das Flag 
im EIFR lösche passiert das-
1
ISR (INT0_vect)          // ISR ext. Interrupt Request 0
2
{
3
  cli();            // Int. sperren
4
  EIFR = (1<<INTF0);      // Int.Flag löschen
5
  _delay_ms(300);
6
  asm("NOP");  
7
  sei();            // Int aktivieren
8
}
Gast #3099189
Lesenswert?
• ▲
▼
Du löscht das Flag vor den 300ms, d.h. wenn da was prellt wird das Flag 
wieder gesetzt und nach dem verlassen der ISR wird diese nochmal 
angesprungen. Schlimmer geht's kaum, dass is die mit Abstand 
schlechteste Variante die ich je gesehen habe.
OP #3099204
Lesenswert?
• ▲
▼
Ingo schrieb:
> Du löscht das Flag vor den 300ms, d.h. wenn da was prellt wird das Flag
> wieder gesetzt und nach dem verlassen der ISR wird diese nochmal
> angesprungen.
Stimmt, da hast du recht!

Schlimmer geht's kaum, dass is die mit Abstand
> schlechteste Variante die ich je gesehen habe.
Na siehst du, dann ist das ja neu für dich ;-)
#3099205
Lesenswert?
• ▲
▼
m. g. schrieb:
>ich möchte per INT0 eine Tasterentprellung machen. Beim Testen (Taster
>wird ganz schnell mehrfach betätigt) wird meine ISR 2 mal ausgeführt!

>Warum?

>Mit cli(); sperre ich doch weitere Interrupts und auch wenn ich das Flag
>im EIFR lösche passiert das-

Deswegen macht man das ja auch nicht so.


ISR (INT0_vect)          // ISR ext. Interrupt Request 0
{
  cli();            // Int. sperren
  EIFR = (1<<INTF0);      // Int.Flag löschen
  _delay_ms(300);
  asm("NOP");
  sei();            // Int aktivieren
}

Das vergisst du alles ganz schnell wieder.
1. Die Interrupts werden vom Controller automatisch gesperrt und 
freigegeben. cli() und sei() haben in einer ISR nichts verloren.
2. Ein delay genauso wenig
3. Das Interrupt Flag wird beim Eintritt in die ISR automatisch 
gelöscht.

Damit bleibt das von deiner ISR übrig:

ISR (INT0_vect)          // ISR ext. Interrupt Request 0
{
  asm("NOP");
}

Tasten werden mit einem Timer entprellt:
http://www.mikrocontroller.net/articles/Entprellung

Lies dir das durch. Was du jetzt machst, ist Stochern im Nebel ohne 
Aussicht auf Erfolg.

mfg.
Gast #3099294
Lesenswert?
• ▲
▼
Thomas Eckmann schrieb:
>Damit bleibt das von deiner ISR übrig:

>ISR (INT0_vect)          // ISR ext. Interrupt Request 0
>{
>  asm("NOP");
>}


Das bringt nur nichts mehr.
Wenn das nach seiner Vorstellung gelöst werden sollte müsste er solange 
in der ISR verbleiben bis der Kontakt sauber steht. Nur düfte das 
schlechte Programmierung sein weil das vermutlich alle anderen 
Interrupts derweil blockiert.

Ich würde das lösen indem ich in der ISR den Auftrag erteilen würde den 
bestimmten Pin-Interrupt zu sperren und einen Timerauftrag starten würde 
der nach festgesetzter Zeit zB 200ms, den Pin-Interrupt wieder frei 
gibt. Der Umweg über den Timer hat den Vorteil dass in der Zwischenzeit 
nichts blokiert wird, weder Interrupts noch sonstiger Programmablauf.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.