PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Int0 wird bei direkt bei 'Enable Int0' ausgelöst - Warum?



malthy
30.08.2010, 17:07
Hallo,

ich habe folgendes Problem: ich möchte, dass eine durch Int0 ausgelöste ISR nur einmal ausgeführt wird, danach nicht mehr. Z.B. soll beim Programmstart die ISR einmal aufgerufen werden, falls das entsprechende Ereignis am Int-Pin stattgefunden hat. Danach soll dieses Ereignis nicht mehr dazu führen, dass die ISR ausgeführt wird. Allerdings möchte ich dieses Verhalten durch eine Art Reset-Funktion zurücksetzen können: wird zB eine bestimmte Taste gedrückt, soll der Controller wieder auf das externe Ereignis warten, einmal die ISR ausführen und danach wieder umempfindlich für Int0 sein. Ich hoffe ich konnte mich verständlich machen, klingt jetzt irgendwie komplizierter als es ist... :-)

Was ich dazu gemacht habe: in der ISR für Int0 wird dieser als erstes direkt ausgeschaltet ("Disable Int0"). An anderer Stelle im Programm wird Int0 dann bedarfsweise wieder aktiviert ("Enable Int0"). Das funktioniert aber nur so "halb": Wenn nach dem "Disable Int0" das externe Ereignis auftritt, wird die ISR zunächst nicht aufgerufen - so weit so gut. Wenn ich dann aber den Int0 wieder einschalte ("Enable Int0") wird die ISR sofort angesprungen obwohl sich nichts an dem entsprechenden Pin getan hat. "Enable Int0" führt aber eindeutig nicht zum Ausführen der ISR, wenn während der "disbale-Phase" nichts passiert ist. Der Controller merkt sich also offensichtlich irgendwo, dass das externe Ereignis da war, auch wenn er den Interrupt dann korrekterweise nicht direkt ausführt. Er meint wohl, er müsste das dann beim nächsten Enable nachholen. Wie kann ich ihm das abgewöhnen?

Vielen Dank schonmal für die Infos, viele Grüße
Malte

uwegw
30.08.2010, 17:44
Ja, beim AVr werden alle Interrupts gemerkt, bis sie abgearbeitet wurden. Das ist nötig, wenn ein Interrupt auftritt, während eine andere ISR auftritt.
Dazu dienen die Interrupt-Flags, die meist in den Registern der jeweiligen Peripherieeinheit zu finden sind. Man kann sie explizit löschen, indem man sie !!! auf 1 setzt !!! (ja, wirklich!).

Für die externen Interrupts sind das z.B. beim Mega8 die Bits INTF0 und INTF1 im Register GICR.

malthy
30.08.2010, 17:54
Vielen Dank! Dann werde ich mal versuchen, diese Bits vor dem Enable zu setzen - das sollte das Problem lösen.

Viele Grüße
Malte

malthy
30.08.2010, 18:10
Nachtrag: ja, das funktioniert erwartungsgemäß perfekt - nur für den Fall das jemand anderes irgendwann mal das gleiche Problem hat...

Danke nochmal!