Hi Zusammen! Nach einem Sleep-Befehl geht es für gewöhnlich doch dort weiter wo der µC schlafen geschickt wurde, oder? Bzw. eigentlich in der Interrupt-Routine wenn der Controller mit einem Interrupt aufgeweckt wird und er springt dann zurück zu der Stelle an der er schlafen geschickt wurde. Soweit richtig? Wenn der µC durch einen Watchdog Interrupt aufgeweckt wird, dort eine Variable hochgezählt wird und dann auch gleich wieder schlafen geschickt wird bis die Variable einen gewissen Wert erreicht hat. Wo geht es dann weiter? Wohin springt das Programm aus der ISR? Der letzte Sleep-Befehl war ja in der ISR. LG Ernst
Sleep ist ein nicht Level Konstrukt,, welches transparent mit einem timerinterrupt verknüpft ist. Der watchdog bedient sich nicht des sleep Befehls und Dr hat seinen eigenen timer und damit verknüpften interrupt
high level schrieb: > Sleep ist ein nicht Level Konstrukt,, welches transparent mit einem > timerinterrupt verknüpft ist. Der watchdog bedient sich nicht des sleep > Befehls und Dr hat seinen eigenen timer und damit verknüpften interrupt Und das heißt jetzt was auf meine Frage bezogen?
kommt auf den Mikrocontroller an, was passiert wenn er aus dem sleep aufwacht, am besten mal ins Datenblatt schauen.
user schrieb: > kommt auf den Mikrocontroller an, was passiert wenn er aus dem sleep > aufwacht, am besten mal ins Datenblatt schauen. µC ist ein ATmega88A Mit den Infos aus dem Datenblatt komme ich nicht weiter: "If an enabled interrupt occurs while the MCU is in a sleep mode, the MCU wakes up. The MCU is then halted for four cycles in addition to the start-up time, executes the interrupt routine, and resumes execution from the instruction following SLEEP. The contents of the Register File and SRAM are unaltered when the device wakes up from sleep." Er macht weiter mit dem Befehl der nach dem sleep Befehl kommt. Aber das beantwortet nicht meine Frage wohin gesprungen wird nach der ISR. Und in der ISR wird der Sleep Befehl zuletzt aufgerufen. Und wohin wird dann aus der ISR gesprungen?
Ernst B. schrieb: > Und in > der ISR wird der Sleep Befehl zuletzt aufgerufen. Das ist jetzt nicht dein Ernst. Der Sleep Befehl darf natürlich nur im main() sein. Gruß Anja
Setze in deiner ISR einfach ein Flag, dass in der main() ausgewertet wird, um den Prozessor ggf. in den Sleep zu schicken.
noch einer schrieb: > Der sleep kommt genau einmal im Main vor Hinter der zusätzlichen Einschränkung "genau einmal" sehe ich jetzt allerdings keinen Sinn.
Ernst B. schrieb: > Wohin springt das Programm aus der ISR? Der letzte Sleep-Befehl > war ja in der ISR. Böse Falle. Entweder ist dann endgültig Schluss, weil sleep mit im Handler abgeschalteten Interrupts eine saubere Einbahnstrasse ist. Oder die Handler stapeln sich bis der Stack platzt. Ergo: In den Handler gehört kein Sleep. Der Sleep gehört ins Hauptprogramm (aber nicht zwangsläufig in die main-Funktion), wo der Zähler untersucht und abhängig davon eingepennt wird. Aber auf race conditions achten, denn wenn zwischen dem Test vom Zähler (oder Flag) und dem Sleep ein Interrupt reinrutschen kann, der ebendies verändert, dann wird das ab und zu ins Auge gehen.
Ernst B. schrieb: > Der letzte Sleep-Befehl > war ja in der ISR. Dann wars das, d.h. der AVR schläft ewig. Sleep darf nur auf Main-Level erfolgen. Peter
Ernst B. schrieb: > Wenn der µC durch einen Watchdog Interrupt aufgeweckt wird Das ist ja nicht das einzige, was er machen soll. Irgendwann wird die Variable ja ausgewertet. Oder z.B. eine Taste gedrückt (Pin Change Interupt) So in etwa: main { sleep(); if (variable >= HIGH) { //Mach was } if (taste) { //Mach was } } ISR(WDT) { variable ++; } ISR(PCINT) { taste = 1; } mfg.
Der Hauptfehler ist, daß viele versuchen, das Stromsparen mit der Funktion zu verknoten. Dadurch wird das Ganze aber unübersichtlich, schwer erweiterbar und fehleranfällig. Zuerst sollte man nur an die Funktion denken und diese implementieren. Und erst, wenn wirklich alles einwandfrei läuft, kommt das Stromsparen hinzu. Das ist dann quasi eine eigenständige Task, die nur durch die Funktion angestoßen wird. Und wenn dann der Code später erweitert werden soll (was fast immer der Fall ist), kann man es deaktivieren, die Änderungen vornehmen, testen und wieder aktivieren. Beitrag "AVR Sleep Mode / Knight Rider" Peter
Deswegen ist es am Besten den Sleep nur an einem Ort im Main zu haben, dann benoetigt man das Drumherum auch nur einmal. Eine Zustandsmaschine muss man ja eh haben.
Pico Oschi schrieb: > Deswegen ist es am Besten den Sleep nur an einem Ort im Main zu haben, > dann benoetigt man das Drumherum auch nur einmal. Nö, das muß nicht besser sein. In meinem Beispiel habe ich je nach Zustand das Sleep an verschiedenen Stellen. Nach dem Power-Down soll ja sofort der Aufwachinterrupt disabled werden. Im Idle ist das aber nicht nötig. Peter
Ich danke Euch für die vielen Antworten. Obwohl ich einen totalen Holler programmieren wollte bin ich doch nicht so unzufrieden mit mir weil mir das Problem noch aufgefallen ist bevor ich es so programmiert habe wie ich ursprünglich wollte. Die Artikel hier zum sleep Modus hatte ich natürlich gelesen, daß man das nicht in der ISR darf kam für mich aber nicht so raus. Siehe A.K.'s Antwort, ist ja auch logisch. @Peter: Die eigentliche Funktion hatte ich eh schon fertig, die funktioniert auch gut. Von dem her war ich eh auf dem richtigen Weg. Den Aufwachinterrupt muß ich nicht zwingend disablen nach dem Power-down wenn der WDT eh zurückgesetzt wird im Main, oder doch? Das sleep enable Bit wird aber gleich nach dem Aufwachen gelöscht wenn ich das richtig gesehen habe. @AK: Das der Interrupt im I-Handler disabled wird habe ich zwar gewußt aber überhaupt nicht dran gedacht. Da hätte ich mir die Frage gleich sparen können. @Anja: Doch, doch, war schon mein Ernst, manchmal stelle ich offenbar dämliche Fragen. :-) Danke Euch Allen Ernst
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.