HI,
ich würde meine Schaltung gerne nach einer gewissen unaktiven Zeit in
den Sleep Modus versetzen. Ich benutze einen ATMEGA32 mit 16 MHZ Takt
und wollte dies über einen Timer realisieren. Also dachte ich mir ich
nehme den 16Bit Timer und lasse diesen laufen. Bei einem Overflow wird
eine volatile Variable hochgezählt und wenn diese den Wert 10 erreicht,
dann wird der Sleep Modus des Atmel eingeschalten.
Nun das mit dem Sleep Modus klappt nur nach ungefähr 10ms schon ;-(. Ich
hatte mir das so gedacht.
16 000 000 Hz / (1024 * 65536) = 0,238s
Das heisst, ein Interrupt bei einem 1024 Prescaler sollte alle 0,24s
eintreffen. Lasse ich die Interruptvariable nun bis 45 zählen, dann
komme ich ungefähr auf 10s.
((16 000 000 Hz) / (1024 * 65536)) * 45 = 10,73s
Leider geht die Schaltung immer sofort in den Sleep Modus. D.h. irgendwo
programmiere ich Mist. Genug der Erklärung, hier der Code.
Wenn du den Idle Modus verwendest, dann würde ich den µC immer in diesen
Modus versetzen und periodisch per Timer wieder aufwecken, um
nachzuschauen ob es was zu tun gibt.
Ansonsten sehe ich in dem Code jetzt eigentlich auch keinen Fehler.
Also er geht nach 5 sek plötzlich aus. Kann nicht wieder eingeschaltet
werden und die rote LED die an PIN D7 hängt geht an. Das check ich
überhaupt nicht.
Ich hab doch noch einen Fehler gefunden, und zwar in deiner Rechnung:
Die Frequenz des Timers beträgt 0,238Hz und nicht 0,238s ! Sind sind
etwa 4,2s.
Der Controller müsste sich also nach 189s schlafen legen.
Matthias wrote:
> Ich will mit> INT0 aufwecken.
Du denkst aber dran, dass auf einem ATmega32 das Aufwecken durch
einen Externinterrupt ausschließlich durch (low-)pegelgesteuerten
Interrupt möglich ist, ja? Die Varianten mit der Flankensteuerung
brauchen für die Erkennung der Flanke einen laufenden IO clock.
Der Pin-Change-Interrupt der neueren AVRs funktioniert meiner
Erinnerung nach dagegen auch ohne IO clock. Du könntest also ggf.
einen Upgrade auf einen ATmega324P erwägen.
@ Jörg
Er verwendet den Idle Modus, da läuft der IO Takt weiter.
@ Matthias
Poste doch mal deine Initialisierung, vom Interrupt und die
Interruptroutine, dann kann man dir vielleicht weiterhelfen.
Wie Jörg schon angedeutet hat: Es gibt noch andere Sleep Modi, die
effektiver sind als der Idle Modus. Der Power Down Modus könnte für dich
interessant sein, dann wird der AVR aber komplett stillgelegt und kann
eben nur durch den Leven Interrupt geweckt werden.
Ich glaube ich habe den Fehler: Du setzt den AVR in einem Interrupt in
den Schlafmodus. Und im Interrupt sind andere Interrupts ausgeschaltet
-> Kein Externer Interrupt, kein Aufwachen.
Was lernen wir daraus: Nicht alles einfach in den Interrupt paken,
sondern im Interrupt Flags setzen die in der Main Schleife dann
abgearbeitet werden.
Daher wird while (IN_SLEEP == 1); auch nie verlassen. Diese Zeile kannst
du dir sparen, denn wenn der Controller schläft, kann er nicht
überprüfen ob er schläft.
Was ich nicht verstehe, wenn ich die Zeile
GREEN_OFF();
RED_OFF();
MCUCR = 0x83;
nehme, hört dann der uC ab MCUCR = 0x83; auf und macht an dieser Stelle
bei einem Interrupt dann weiter oder was macht der im Schlafmodus, wo
fängt er wieder an ?
Also erstens dass mit den Interrupts im Interrupt war der Hauptfehler
und du hattest natürlich vollkommen recht.
Zweitens fehlte bei mir ein sleep_cpu(); bzw. ein asm("sleep") dann geht
das
Matthias wrote:
> nehme, hört dann der uC ab MCUCR = 0x83; auf und macht an dieser Stelle> bei einem Interrupt dann weiter oder was macht der im Schlafmodus, wo> fängt er wieder an ?
Nö. Der hört da gar nicht auf. Das "MCUCR = 0x83;" setzt lediglich das
Sleep-Enable (und konfiguriert nebenbei den externen Interrupt 0 auf
"steigende Flanke"). Geschlafen wird erst dann, wenn der Befehl "sleep"
ausgeführt wird.
Matthias wrote:
> Genau das habe ich gerade gesagt ;-) und "für mich" festgestellt
Schön... Und wenn ich vor dem Absenden aktualisiert hätte, hätte ich mir
das ganze glatt sparen können.
Ich denke übrigens, dass du durchaus auch aus einer IRQ heraus den
sleep mode anwerfen kannst (auch wenn ich es unästhetisch finde :).
Das Aufwachen hängt nicht davon ab, ob der Interupt gerade wirklich
in eine ISR gehen kann oder nicht, die CPU fängt trotzdem wieder
an zu arbeiten. Danach wird die alte ISR zu Ende abgearbeitet, und
gleich nach der Rückkehr aus dieser die ISR für den Externinterrupt.
Jörg Wunsch wrote:
> Ich denke übrigens, dass du durchaus auch aus einer IRQ heraus den> sleep mode anwerfen kannst (auch wenn ich es unästhetisch finde :).> Das Aufwachen hängt nicht davon ab, ob der Interupt gerade wirklich> in eine ISR gehen kann oder nicht, die CPU fängt trotzdem wieder> an zu arbeiten.
Sicher ? Ich habe mich das auch gefragt, und nichts dazu im Datenblatt
gefunden. Dann habe ich mir das überlegt:
Sobald ein Interrupt eintritt, wird automatisch das globale Interrupt
Enable Flag gelöscht, demzufolge alle Interrupts deaktiviert. Erst beim
reti (=ret + sei in einem) werden die Interrupts wieder freigeschaltet.
Doch noch eine kleine Frage zum Abschluss. Wenn ich wie oben beschrieben
den Sleep Modus durch einen externen Interrupt an INT0 verlasse, wie
weit kann ich dann den Stromverbrauch meines Atmels senken. Ich würde in
dieser Hinsicht gerne das absolute Maximum rausholen.
Sicher, dass Du den Interrupt als Level-Interrupt konfiguriert hast?
Oben war er nämlich noch auf "steigende Flanke" gesetzt, wenn ich mich
recht erinnere...
Außerdem kannst du ihn auch mit einem flankengesteuerten Interrupt an
INT2 (aber nur an diesem) aus dem Sleep befördern:
`` ... Low level interrupts on INT0/INT1 and the edge interrupt on
INT2 are detected asynchronously. This implies that these interrupts
can be used for waking the part also from sleep modes other than Idle
mode. The I/O clock is halted in all sleep modes except Idle mode.''
You are the Best :-)
Genau das war es. Ich habe die angewohnheit nicht zwischen den Zeilen zu
lesen und deshalb solche die wie "LEVEL" Interrupt mal schnell zu
überlesen. Jetzt geht es einwandfrei und ich sag mal wieder: Danke dir !
Würde die ganze Schaltung nämlich gerne über eine Solarzelle betreiben,
habe allerdings keine Ahnung von Solarzellen. Vielleicht weiss jemand ob
man bei so einem Nennstrom eine Versorgung über z.B. 2 Batterien mit
Solarzellenanbindung hinkriegt. Kennt ihr da Projekte ?
68 mA ist viel zu viel. Das liegt nicht am Atmel sondern an dem
drumherum, wie spannungsregler, pull-up widerstände ...
vielleicht solltest du deine schaltung auch mal posten
Für stromsparenden Betrieb solltest du dir auch einen moderneren
Prozessor zulegen. Den ATmega324P hatte ich ja schon einmal genannt.
Der Grundverbrauch im aktiven Betrieb würde dadurch von 23 mA auf
13 mA sinken. Im Powerdown sinkt der Strom von 1 µA auf 0,6 µA, das
wirst du aber kaum merken. ;-)
Der Reset deiner Schaltung braucht vermutlich tatsächlich ein
Redesign...
@ Matthias (Gast)
>Krieg meine Schaltung mit dem Power-down Mode jetzt von 162 mA auf 68>mA. Mehr geht wahrscheinlich am Atmel selbst nicht oder ?
???
Der AVR braucht im tiefsten Sleep Modus (Power down) 1-2uA
(MIKROAmpere).
MFG
Falk
Ja ja ja :-) is ja schon gut ich weiss das es nicht der Atmel ist. Also
zu meiner Schaltung:
Bisher noch auf der Platine jedoch bald draussen sind:
1 x MAX232
1 x poti 150 Ohm
Dazu kommt allerdings ein PIR Sensor der jedoch auch so gut wie nix
ziehen soll. Ich frag mich nur ob der LM1086 3,3 soviel zieht. Das kann
ich mir nicht vorstellen und Pull-ups verwende ich keine.
Ich habe noch eine SD-Karte und eine UART Camera dranhängen. Die Cam
versetze ich in den Sleep Modus und dann zieht die nur noch 100 uA. Alsp
geh ich jetzt gleich nochmal an den Lötkolben und bau oben genannte
Teile weg, da sie keinen nutzen haben (ist ja nur ne Testplatine).
So nu bin ich bei ca. 27 mA was immer noch zu viel ist, allerdings sieht
es auf der Testplatine echt wüst aus und bevor ich da weitermache, mach
ich ne neue mit dem MEGA(L).
Meine letzte Frage wäre nur noch: Kennt jemand eine Beschaltung, wo ein
Akku per Solarzelle geladen wird, jedoch die Schaltung sich gleichzeitig
von diesem versorgt. Ich bin auf dem Gebiet vollkommen unerfahren und
würde mich mit Ladeschaltungen von Akkus über Solarzellen gerne mal
informieren.