Hy Leute,
Ich arbeite gerade mit dem ATMEGA32L und soll so energiesparend wie
möglich programmieren. Dafür möchte ich alle _delay_ms(); durch eine
eigene Routine ersetzen, welche den µC für diese Zeit in den Idle-Mode
schickt.
Ich habe das Programm außerhalb meines Hauptprogramms zur Testung
geschrieben.
Da die Variante mit Timer1 und ISR(TIMER1_COMPA_vect); nicht
funktioniert hat, kommentierte ich diese aus und versuchte es mit einem
externen Interrupt.
Doch leider komm ich auf das selbe Ergebnis, die LED (welche mir als
Kontrolle dient) schaltet sich ca. alle 5s ein und nach weiteren 5s
wieder aus.
Ich konnte in anderen Beiträgen, bzw. im GCC Tutorial keinen Unterschied
zu meinem Programm entdecken...
Vielen Dank im Voraus!
ghost schrieb:> Da die Variante mit Timer1 und ISR(TIMER1_COMPA_vect); nicht> funktioniert hat,
Das geht auch nicht. Im Sleep ist der Takt abgeschaltet. Dann hat der
Timer nichts zum zählen.
ghost schrieb:> Doch leider komm ich auf das selbe Ergebnis, die LED (welche mir als> Kontrolle dient) schaltet sich ca. alle 5s ein und nach weiteren 5s> wieder aus.
Wo kommen denn die 5s her? Und wieso dasselbe Ergebnis? Dasselbe wie
was?
mfg.
Thomas Eckmann schrieb:> ghost schrieb:>> Da die Variante mit Timer1 und ISR(TIMER1_COMPA_vect); nicht>> funktioniert hat,>> Das geht auch nicht. Im Sleep ist der Takt abgeschaltet.
Nein.
> ghost schrieb:>> Doch leider komm ich auf das selbe Ergebnis, die LED (welche mir als>> Kontrolle dient) schaltet sich ca. alle 5s ein und nach weiteren 5s>> wieder aus.>> Wo kommen denn die 5s her?
Ich hätte 2,2 erwartet, wenn das Schlafen nicht funktioniert.
> Und wieso dasselbe Ergebnis? Dasselbe wie was?
Das selbe wie mit Timer?
ghost schrieb:> #define EXT_INT0_PIN PD3> #define EXT_INT1_PIN PD2
Das ist falsch. Laut Datenblatt ist PD2 INT0 und PD3 INT1.
Thomas Eckmann schrieb:> Das geht auch nicht. Im Sleep ist der Takt abgeschaltet. Dann hat der> Timer nichts zum zählen.
Wasn Quatsch.
Natürlich läuft alle Peripherie im Idle weiter, nur die CPU wird
angehalten.
Die Stromeinsparung ist daher auch nicht sonderlich hoch (~50%).
Ich weiß leider auch nicht warum es 5s sind... die Frequenz (soft- und
hardwaretechnisch) stimmt.
Das mit INT0 und INT1 ist in diesem Fall egal, weil beide gleich
beschaltet werden, aber danke.
Ja genau, ich erhalte mit externem Interrupt und Timer1 dasselbe
Ergebnis => kein Idle-Mode, LED schaltet sich alle 5s ein und aus. Auch
der Stromverbrauch sinkt nicht während der Messung nicht(nur der Strom
der LED bei EIN/AUS).
Thomas P. schrieb:> LED schaltet sich alle 5s ein und aus.
Dann stimmt Dein F_CPU nicht.
Im Code hast Du ja 10 * 0,2s stehen.
Du mußt das nicht verklausulieren, _delay_ms verträgt bis 6,5535s.
Was sollen die Delays überhaupt, schmeiß sie raus und nimm den Timer.
Mein F_CPU ist auf 1MHz eingestellt, softwaretechnisch und
hardwaretechnisch.
Auszug aus delay.h:
"The maximal possible delay is 262.14 ms / F_CPU in MHz."
Die Delays habe ich, um den Strom besser messen zu können.
Ich glaube nicht, dass es an den _delay_ms() liegt...
Thomas P. schrieb:> Auszug aus delay.h:> "The maximal possible delay is 262.14 ms / F_CPU in MHz."
Wenn's danach nicht weitergeht hast du aber noch eine sehr, sehr alte
Version davon installiert.
Die nächsten Sätze wären nämlich:
When the user request delay which exceed the maximum possible one,
_delay_ms() provides a decreased resolution functionality. In this mode
_delay_ms() will work with a resolution of 1/10 ms, providing delays up
to 6.5535 seconds (independent from CPU frequency). The user will not be
informed about decreased resolution.
Und die "decreased resolution" ist sicher noch besser als
Selbst-Zusammenstöpseln von Einzel-Delays in einer Schleife.
Ich weiß, dass es nachher noch weiter geht! Aber ich wollte die maximal
erreichbare Genauigkeit, da ich mit dem Oszi alles kontrolliere.
Aber darum geht es ja jetzt nicht. Ich möchte wissen, ob jemand einen
Tipp hat, warum mein µC nicht in den Idle-Mode geht bzw. was ich
vergessen oder falsch gemacht habe!
Thomas P. schrieb:> Aber darum geht es ja jetzt nicht. Ich möchte wissen, ob jemand einen> Tipp hat, warum mein µC nicht in den Idle-Mode geht bzw. was ich> vergessen oder falsch gemacht habe!
Ich habe mir Mal erlaubt, dein Programm in der Timerversion laufen zu
lassen.
Atmega644, 1MHz, Prescaler = 64
Ah, ok, das hab ich falsch verstanden!
Ich dachte, sleep_mode() ist die Zusammenfassung von sleep_enable() und
sleep_cpu()? Warum benötige ich hier beides?
Ich kann leider trotzdem keine Änderung des Stromes messen... 17mA (ohne
Status-LED), weniger bekomm ich nicht!
Peter Dannegger schrieb:> Dann stimmt Dein F_CPU nicht.> Im Code hast Du ja 10 * 0,2s stehen.
11 * 0,2 s.
Thomas P. schrieb:> Die Delays habe ich, um den Strom besser messen zu können.
Ja, aber wenn da 5 statt 2,2 Sekunden rauskommen und die Taktrate
korrekt für das Delay angegeben ist, sind das 2,8 Sekunden zuviel. Die
müssen ja irgendwo herkommen.
Thomas P. schrieb:> Ich weiß, dass es nachher noch weiter geht! Aber ich wollte die maximal> erreichbare Genauigkeit, da ich mit dem Oszi alles kontrolliere.
Die verlierst du durch deine Schleife außenrum aber auch. Und wenn der
Takt vom internen R/C-Oszillator stammen sollte, ist der außerdem noch
deutlich ungenauer.
Thomas P. schrieb:> Ich dachte, sleep_mode() ist die Zusammenfassung von sleep_enable() und> sleep_cpu()? Warum benötige ich hier beides?
Benötigst du nicht. Da habe ich einfach nur zuviel wieder
"einkommentiert".
Ich hab das Ganze jetzt ein wenig zusammengestrichen:
Thomas P. schrieb:> Ich kann leider trotzdem keine Änderung des Stromes messen... 17mA (ohne> Status-LED), weniger bekomm ich nicht!
Sleep Idle ist nicht sehr effektiv.
Bei mir beträgt der Unterschied 1,3mA (84,4mA : 83,1mA).
Auf meinem Testboard ist aber noch einiges mehr drauf. Der 644P
verbraucht ca. 10mA bei 5V. Also gut 10% Ersparnis im Sleep.
Bei 3V beträgt der Unterschied nur noch 0,4mA.
mfg.