Hallo zusammen, mein von einem ATMega8 portierter Code sorgt aus einem AT45 für Probleme, der sleep wird direkt wieder verlassen, insofern ich den INT0 freigebe (ist hier auskodiert und dann geht er sauber auf 70uA runter). Wieso? if(mode==5 || off==1) { PORTB = 0x00000001; // Alle Ausgänge aus, unbenötigte Pull-ups aus off=0; MCUCR |= 0b00001000; // Sleep Mode PWR_DOWN setzen + Enable //GIMSK |= 0b01000000; // Externen Interrupt INT0 freigeben set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); // Enter Sandman ...zzzZZZ GIMSK &= 0b10111111; // Externen Interrupt INT0 sperren PORTB = 0x00010001; // PortB wieder konfigurieren mode=1; } Danke & Gruß, Klaus.
Oups, der Bedientaster, der die modes wechselt hängt an INT0...das dürfte das Problem sein, er ist quasi in dem Moment noch gedrückt?! Klaus.
Ne, das wars auch nicht...eine Verzögerung von 500ms nach Eintritt in "mode 5" führt zum gleichen Ergebnis. Hmmm... Klaus.
Klaus2 schrieb: > PORTB = 0x00000001; Du versuchst einen 32bit Wert in ein 8bit register zu schreiben... Ich nehme einfach mal an das sollte "0b..." heißen und nicht "0x..."
Das lief aufm AT8 auch so :) Nichts desto trotz habe ich auch bereits gesehen und pro forma geändert, bringt aber nichts. Klaus.
Ratlosigkeit. Laut Datenblatt ist das doch ein lowlevel INT0 Interrupt, der den sleep beendet? Aber selbst wenn ich INT0 auf VCC lege, geht er sofort wieder aus dem sleep. Setze ich GIMSK komplett auf 0x00, bleibt er brav im sleep (ist dann aber natürlich nicht mehr weckbar). Nun, vll schlafe ich eine Nacht drüber... Klaus.
OK, beim Freigeben des INT0 wird die ISR angesprungen und dann schlafen gegangen - wieso bitte springt der in die ISR, wenn man den I freigibt? Hab ich da beim AT45 was übersehen? Aktuell: if(mode==5 || off==1) { PORTB = 0b00000001; // Alle Ausgänge aus, unbenötigte Pull-ups aus off=0; _delay_ms(500); MCUCR &= 0b11111100; // Low Level Interrupt MCUCR |= 0b00010000; // Sleep Mode PWR_DOWN GIMSK |= 0b01000000; // Externen Interrupt INT0 freigeben set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); // Enter Sandman ...zzzZZZ GIMSK &= 0b10111111; // Externen Interrupt INT0 sperren PORTB = 0b00010001; // PortB wieder konfigurieren mode=1; } Klaus.
Klaus2 schrieb: > > PORTB = 0b00000001; // Alle Ausgänge aus, unbenötigte Pull-ups aus Dein Taster hat einen externen Pullup? (INT0 liegt auf PB2) Schönes Wochenende
Es ist gute Praxis, wenn du den IRQ nach dem Freigeben nochmal löschst, um etwaige anstehende Requests zu eliminieren:
1 | GIMSK |= (1 << INT0); // ext. irq |
2 | GIFR |= (1 << INTF0); // clear pendings |
3 | |
4 | // and now we are ready to enter the sleep mode.
|
Es kann übrigens sinnvoll sein, besser einen Pinchange Interrupt zu nehmen und auf eine Flanke zu warten statt auf low. Pinchange Interrupts brauchen dafür auch im Gegensatz zu INT0 keine laufende I/O Clock.
:
Bearbeitet durch User
Flohzirkus, meine Rettung. Ich Volldödel hab die ganze Zeit an PCINT0 rumgepegelt, der Taster war einfach nur falsch angeschlossen. Nun, bin ich wenigstens doch nicht zu doof funktionierenden Code zu schreiben, nein, es geht schon bei viel banaleren Dingen los :) Danke & Gruß, ich hol jetzt mal Brötchen... :) Klaus.
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.