Hallo,
ich habe meinem STM32L151 in den letzten zwei Tagen das Stromsparen
beigebracht und bin von 12 mA schon auf 7 mA runter gekommen. Mich würde
aber interessieren ob da noch mehr (oder weniger) gehen würde.
Der Chiptakt ist 32 MHz, daran kann ich auch nichts ändern da ich nur
mit hohem Chiptakt eine gute Auflösung für einen Timer hinbekomme.
Dieser löst ca alle 40 µs einen Interrupt aus, welcher bearbeitet wird
bevor der STM mit einem __WFI() wieder schlafen geschickt wird.
Abgeschalten habe ich bereits den ADC mitsamt DMA und dazugehörige
Clocks. Nur bei Bedarf werden 3 Messungen durchgeführt bevor der ADC mit
DMA wieder abgeschalten wird.
Bislang habe ich aber keine Möglichkeit gefunden den Stromverbrauch
weiter zu reduzieren. Mehr als den SLEEP-Modus kann ich nicht verwenden,
da ab dem STOP-Modus die Takte angehalten werden und somit auch mein 40
µs Interrupt ausbleiben würde.
Gibt es doch noch andere Tricks?
Zitat aus dem Datenblatt zum STM32L15xxD:
230 µA/MHz Run mode
Das macht bei 32 MHz:
32 * 0,23 = 7,36 mA
Sprich, du bist schon gut "am Anschlag" beim Rest deiner Peripherie usw.
Wie viel musst du in dem Timer-Interrupt rechnen?
Edith: Hast du mal versucht, in deiner Hauptschleife die CPU anzuhalten
(bin grad nicht sicher, wie das Kommando dazu heißt), sodass sie durch
den Interrupt weiterläuft ... bis sie wieder die "Haltestelle" erreicht?
Im RM0038 steht das unter Punkt 5.3, Seite 103, Tabelle 26
WFI
CPU CLK OFF
no effect on other
clocks or analog
clock sources
(WFI = Wait For Interrupt)
Phantomix Ximotnahp schrieb:> Hast du mal versucht, in deiner Hauptschleife die CPU anzuhalten> (bin grad nicht sicher, wie das Kommando dazu heißt), sodass sie durch> den Interrupt weiterläuft ... bis sie wieder die "Haltestelle" erreicht?
__WFI();
__enable_irq();
__ISB();
__disable_irq();
Coder schrieb:> Was passiert im Interrupt?
Im Interrupt wird ein neues Sample mit dem DAC ausgegeben.
Lothar schrieb:> __WFI();> __enable_irq();> __ISB();> __disable_irq();
__WFI(); hatte ich bereits ans Ende dem main-loops eingebaut und hat
eine ordentliche Stromersparnis gebracht. Die Interrupts kann ich aber
nicht deaktivieren, da diese den µC ja wieder aufwecken sollen!
Uwe Bonnes schrieb:> Gibt es unbeschaltetet Eingaenge? Die ziehen gerne Querstrome. Mit> den internen Pull-Up/Down verhinderst du das Driften der Eingaenge!
Was verstehst du unter "unbeschaltene Eingaenge"? Es gibt so einige Pins
die in der Luft hängen, diese werden aber ohnehin im Programm nicht
initialisiert.
Besten Dank für die bisherigen Antworten, ich bin sehr beruhigt dass ich
das meiste bereits ausgereizt habe :D
Chris schrieb:> Dieser löst ca alle 40 µs einen Interrupt aus, welcher bearbeitet wird
Da würde ich ansetzen.
Warum müssen es 40µs sein und 32MHz?
Viele MCs haben RTC und Pin-Change zum Aufwachen, um komplett zu
schlafen, bis es etwas zu tun gibt.
Chris schrieb:> Was verstehst du unter "unbeschaltene Eingaenge"? Es gibt so einige Pins> die in der Luft hängen, diese werden aber ohnehin im Programm nicht> initialisiert.
Genau das.
Wenn Pins floaten, können beide FETs des Eingangsgatters leiten und
erhöhen damit den Stromverbrauch merklich.
Nehmen wir mal 100µA an, sind das bei 64 Eingängen schon 6,4mA.
Bei unbenutzten Pins sollte wenigstens der Pullup an sein.
Chris schrieb:>> __WFI();>> __enable_irq();>> __ISB();>> __disable_irq();> __WFI(); hatte ich bereits ans Ende dem main-loops eingebaut und hat> eine ordentliche Stromersparnis gebracht. Die Interrupts kann ich aber> nicht deaktivieren, da diese den µC ja wieder aufwecken sollen!
Das ist ja genau der Trick: auch wenn die Interrupts deaktiviert sind
(was noch etwas mehr Strom spart), führt WFI zum Aufwecken (der
aufweckende Interrupt wird dann Pending). Dann werden mit enable_irq die
Interrupts aktiviert, und durch ISB wird genau ein Assembler-Befehl
ausgeführt, und das ist der Sprung in Deinen Interrupt-Handler (dorthin
müsstest Du die Bearbeitung verlegen). Sobald der fertig ist, erfolgt
der Rücksprung ins Hauptprogramm und die Interrupts werden wieder mit
disable_irq deaktiviert. Und dann kommt wieder WFI
Coder schrieb:> Was passiert im Interrupt?
Sorry, hatte die Frage übersehen. Im Interrupt wird nur ein neues Sample
mit dem DAC ausgegeben und anschließend ein neuer Wert für den nächsten
Interrupt berechnet, also keine große Sache.
Lothar schrieb:> __WFI();> __enable_irq();> __ISB();> __disable_irq();
Ich habe das eben mal getestet, das Programm läuft nach wie vor ohne
Probleme, der Stromverbrauch ist allerdings "deutlich" hoch gegangen (um
ca 1 mA).
Peter Dannegger schrieb:> Wenn Pins floaten, können beide FETs des Eingangsgatters leiten und> erhöhen damit den Stromverbrauch merklich.> Nehmen wir mal 100µA an, sind das bei 64 Eingängen schon 6,4mA.>> Bei unbenutzten Pins sollte wenigstens der Pullup an sein.
Deinen Vorschlag habe ich ebenfalls getestet und tatsächlich noch etwas
herausholen können. Im Manual hatte ich schon mal darüber gelesen, dass
die Konfiguration als analoger Eingang empfohlen wird. Mit der
Kombination analog (GPIO_Mode_AN) und PullDown (GPIO_PuPd_DOWN) bin ich
mittlerweile bei 6,4 mA (RMS) gelandet, das muss erst mal genügen :)
Chris schrieb:>> __WFI();>> __enable_irq();>> __ISB();>> __disable_irq();> Ich habe das eben mal getestet, das Programm läuft nach wie vor ohne> Probleme, der Stromverbrauch ist allerdings "deutlich" hoch gegangen (um> ca 1 mA).
Hast Du ausser dem Timer-IRQ zum Aufwecken noch andere IRQ? Kannst Du
die Weglassen bzw. alles im Timer-ISR erledigen?
Überhaupt versuchen, alle nichtbenötigten peripheral Clocks
abzuschalten. Wenn du die Genauigkeit vom HSE nicht brauchst, versuchen
mit HSI zu arbeiten
Lothar schrieb:> Hast Du ausser dem Timer-IRQ zum Aufwecken noch andere IRQ? Kannst Du> die Weglassen bzw. alles im Timer-ISR erledigen?
Nein, da ist nicht mehr viel machbar. Ich habe ohnehin nur noch einen
einzigen Timer sowie zwei externe Interrupts. Ich benötige aber alle, da
alle auf verschiedene aber gleich wichtige Ereignisse warten.
Phantomix Ximotnahp schrieb:> Wenn du die Genauigkeit vom HSE nicht brauchst, versuchen mit HSI zu arbeiten
Hatte ich schon einmal getestet, aber keine große Veränderung
feststellen können. Ich habe mich dann dazu entschieden den HSE zu
verwenden
Bin aber wie gesagt schon ganz zufrieden mit der Einsparung :)
Lothar schrieb:> Das ist ja genau der Trick: auch wenn die Interrupts deaktiviert sind> (was noch etwas mehr Strom spart), führt WFI zum Aufwecken (der> aufweckende Interrupt wird dann Pending).
Wozu das denn? Wo ist der Vorteil gegenüber einfach "while(1) __WFI ();"
? Da schläft die CPU genauso bis ein Interrupt kommt, der wird
ausgeführt, und die CPU geht wieder schlafen.
Chris schrieb:> Was verstehst du unter "unbeschaltene Eingaenge"? Es gibt so einige Pins> die in der Luft hängen, diese werden aber ohnehin im Programm nicht
Genau solche Beinchen. Die Pins laden sich ueber Leckstroeme im Chip und
aussen auf und schweben dann irgendwo zwischen Masse und VCC. Je naeher
die Pins an VCC/2 liegen, umso groesser ist der Querstrom.
Es ist durchaus möglich durch die Compiler Einstellungen noch Strom zu
sparen. Ob das bei dem Umfang deines Codes allerdings etwas bringt weiß
ich nicht.
Prinzipiell sollte jedenfalls auf Zeit optimiert werden nicht auf
Speicherplatz.
Auch das Aufrufen von Unterfunktionen benötigt in der Regel mehr Strom.
Daher ist bei stukturierter Programmierung der inline Befehl zu
empfehlen.
Mathematische Berechnungen möglichst vermeiden oder versuchen auf
Controller eigene Bibliotheken umzusteigen. Was der STM32 für deinen
Rechenaufwand hergibt weiß ich natürlich nicht.
Gut ist auch Schleifen möglichst abwärts zählen zu lassen statt
aufwärts.
Außerdem ist es sinnvoll die Schleifenzahl gering zu halten. Nicht nur
ansich die Anzahl der Schleifen sondern auch die Anzahl der durchläufe,
also bei einer hohen Anzahl nach Möglichkeit einen Teiler finden und
lieber den Code noch einmal einkopieren.
Und dann natürlich call-by-reference und all so ein Kram. Aber da bist
du sicher schon selbst drauf gekommen.
Wenn es dich stark interessiert verantstalltet gerade STM jedes Jahr
kostenlose Seminare zur Low-Power-Programmierung. Sind natürlich von
Verkaufsgelaber überflutet, aber es sind nützliche Tipps dabei und die
kennen ihre Controller eben sehr gut und können viele Fragen gezielt
beantworten. Allerdings sind dieses Jahr in Deutschland glaube ich keine
mehr vorgesehen.