Hallo, bei der Vergewaltigung der Arduino IDE durch Umgehung der "Nutzfunktionen" bin ich derzeit an einer Interruptgeschichte über den INT0 dran. Leider weiss ich nicht ganz genau wann welches Bit gesetzt wird. Int Ereignis -> INTF0 ISR Routine -> CLI -> INTF0 = 0? Habe erstmal diese Makros definiert: #define INT0_DISABLE GIMSK &= ~_BV(INT0) #define INT0_ENABLE GIMSK |= _BV(INT0) #define INT0_CLEAR_PENDING GIFR |= _BV(INTF0) Wann genau wird das INTF0 gelöscht durch die Hardware? Beim Eintritt in die Routine oder beim Raustritt? Ich brauche das nämlich damit mir keine Pending Ints direkt nach der ISR wieder reinhauen, wenn SEI die Global Ints wieder zulässt. Ne blöde Frage: Wie kann man bei einem Level Interrupt verhindern, dass der ständig aufgerufen wird, wenn der Puls etwas länger ist als die Reaktionszeit der CPU? Wenn der ADXL345 Sensor nämlich seinen FIFO Overflow INT Pin auf HIGH lässt während meine CPU im Tiefschlaf schläft, dann kommt sie nie wieder da raus, wenn ich RISING einstelle. Idle Mode wäre eine Läsung aber mehr Strom eben. Gruss, Christian
Christian J. schrieb: > Wann genau wird das INTF0 gelöscht durch die Hardware? Beim Eintritt in > die Routine oder beim Raustritt? Ich brauche das nämlich damit mir keine > Pending Ints direkt nach der ISR wieder reinhauen, wenn SEI die Global > Ints wieder zulässt. Das Flag wird am Anfang gelöscht, wenn der Controller auf den Interrupt-Vektor springt. Von einer ISR weiss er gar nichts. > Ne blöde Frage: Wie kann man bei einem Level Interrupt verhindern, dass > der ständig aufgerufen wird, wenn der Puls etwas länger ist als die > Reaktionszeit der CPU? Wenn der ADXL345 Sensor nämlich seinen FIFO > Overflow INT Pin auf HIGH lässt während meine CPU im Tiefschlaf schläft, > dann kommt sie nie wieder da raus, wenn ich RISING einstelle. Idle Mode > wäre eine Läsung aber mehr Strom eben. Das verstehe ich jetzt überhaupt nicht. mfg.
Thomas Eckmann schrieb: > Das verstehe ich jetzt überhaupt nicht. Bei einem Level IRQ wird solange immer eine neue Anforderung erzeugt, wie das Signal anliegt. D.h. es passiert oft bei mir, dass er sofort nach Verlassen der ISR direkt wieder reinspringt, weil das Pending Bit gesetzt wurde. Vermutlich muss man das einfach nur löschen mit "1", ich hatte angenommen dass "0" es löschen würde.
Christian J. schrieb: > Thomas Eckmann schrieb: >> Das verstehe ich jetzt überhaupt nicht. > > Bei einem Level IRQ wird solange immer eine neue Anforderung erzeugt, > wie das Signal anliegt. D.h. es passiert oft bei mir, dass er sofort > nach Verlassen der ISR direkt wieder reinspringt, weil das Pending Bit > gesetzt wurde. Vermutlich muss man das einfach nur löschen mit "1", ich > hatte angenommen dass "0" es löschen würde. Ein Interrupt-Flag wird mit 1 gelöscht. Und zwar mit:
1 | GIFR = (1 << INTF0); |
Aber nicht so:
1 | GIFR |= (1 << INTF0); |
Das würde alle anderen Flags auch loeschen. mfg.
Christian J. schrieb: > während meine CPU im Tiefschlaf schläft, > dann kommt sie nie wieder da raus, wenn ich RISING einstelle. Zum Aufwachen besser den Pin-Change-Interrupt nehmen. Der Level-Interrupt ist nur sinnvoll für Peripherie mit mehreren Interruptquellen. Man springt dann solange wieder in den Interrupt, bis alle Quellen abgearbeitet sind.
Peter Dannegger schrieb: > Christian J. schrieb: >> während meine CPU im Tiefschlaf schläft, >> dann kommt sie nie wieder da raus, wenn ich RISING einstelle. > > Zum Aufwachen besser den Pin-Change-Interrupt nehmen. > > Der Level-Interrupt ist nur sinnvoll für Peripherie mit mehreren > Interruptquellen. Man springt dann solange wieder in den Interrupt, bis > alle Quellen abgearbeitet sind. Dankie für den Tip mit dem I-Flag, hätte das jetzt glatt falsche gemacht. Aber mal ein paar allgemeine Fragen. Auch wenn ich bisher alles ans Rennen gekriegt habe. Ich habe den Attiny84 an einen ADXL345 geflanscht. Der Chip ist buggy, die Z-Achse ist bei allen 5 Stück kaputt, das wurde auch vom Händler bestätigt. Ihr Offset liegt weit außerhalb des Kalibrierbereichs. Aber das soll nicht das Thema sein. Peter, Du würdest also den Rising Int, der so sein muss vor dem Sleep auf Pin Change umschalten, damit auch der PWR-DOWN Mode genutzt werden kann? der ADXL345 löst alle 4s einen INT aus, wenn sein FIFO voll ist. Und wenn die CPU wach ist wieder auf Rising umstellen?
Christian J. schrieb: > Peter, Du würdest also den Rising Int, der so sein muss vor dem Sleep > auf Pin Change umschalten, damit auch der PWR-DOWN Mode genutzt werden > kann? der ADXL345 löst alle 4s einen INT aus, wenn sein FIFO voll ist. > Und wenn die CPU wach ist wieder auf Rising umstellen? Ich weiss ja nicht, was Peter empfiehlt, aber ich würde nur den Pinchange nehmen und den Pin-Status am Anfang der ISR abfragen. Das setzt aber voraus, dass der auch mindestens so lange anliegt. mfg.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.