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?
Gibt es unbeschaltetet Eingaenge? Die ziehen gerne Querstrome. Mit den internen Pull-Up/Down verhinderst du das Driften der Eingaenge!
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.
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.