Oszczędzanie energii w mikrokontrolerach STM32

Zmniejszenie poboru energii przez mikrokontroler można osiągnąć poprzez zmniejszenie częstotliwości jego taktowania (co wiąże się ze spowolnieniem działania) lub przez selektywne wyłączanie układy peryferyjnych wbudowanych w jego strukturę. Ten drugi mechanizm doskonale sprawdza się w mikrokontrolerach STM32, które są konstrukcyjnie przystosowane do selektywnego włączania i wyłączania większości wbudowanych bloków peryferyjnych.

 

 

Zaczniemy od omówienia dostępnych trybów oszczędnościowych, których działanie przetestowano na zestawie STM3210B–EVAL/A.

Sleep mode

Ten tryb oszczędzania energii jest integralną częścią rdzenia Cortex-M3, dlatego informacji na jego temat należy szukać nie w dokumentacji przygotowanej przez producenta mikrokontrolerów STM32, ale w opisie rdzenia przygotowanej przez firmę ARM.
W trybie sleep mode wyłączany jest rdzeń, natomiast wszystkie bloki peryferyjne i źródła sygnałów zegarowych są aktywne. Czas wyjścia z trybu uśpienia i powrót do normalnej pracy mikrokontrolera jest najkrótszy ze wszystkich dostępnych pośród trybów obniżonego poboru mocy. Natężenie prądu pobieranego ze źródła zasilania zależy przede wszystkim od częstotliwości pracy generatorów przebiegów taktujących i aktywnych bloków peryferyjnych. W skrajnym przypadku, gdy mikrokontroler pracuje z zegarem 72 MHz (włączone HSE i PLL) i są włączone wszystkie peryferia, mikrokontroler może pobierać blisko 15 mA. Drugim skrajnym przypadkiem jest praca rdzenia z taktowaniem 125 kHz przy wykorzystaniu wewnętrznego oscylatora HSI i po wyłączeniu wszystkich peryferiów. W takich warunkach mikrokontroler pobiera prąd o natężeniu nie przekraczającym 0,5 mA.
Zależnie od zastosowanych mechanizmów „usypiania” i „wybudzania” rozróżniane jest kilka rodzajów trybów pracy. Za sterowanie tymi trybami odpowiadają dwie instrukcje: WFI (Wait For Interrupt) oraz WFE (Wait For Event). Są to rozkazy asemblerowe, ich użycie w programie napisanym w C wymaga zastosowania podwójnego podkreślenia w roli przedrostka. Przykładowo: żeby wywołać instrukcję WFI należy zastosować zapis:
__WFI();

Sleep-on-exit

Wykorzystanie instrukcji WFI umożliwia między innymi wprowadzenie rdzenia w stan sleep-on-exit. Rdzeń w takim przypadku jest wprowadzany w tryb uśpienia dopiero po zakończeniu obsługi wszystkich przerwań. Wyjście z trybu jest wówczas, gdy w systemie zostanie wykryte żądanie obsługi przerwania. Fragment programu, który działa w opisany sposób przedstawiono na list. 1. Nadzór nad trybami uśpienia sprawowany jest przez NVIC, dlatego wykorzystano funkcje sterujące jego pracą.

List. 1. Fragment programu ilustrującego tryb oszczędzania energii sleep-on-exit

Przerwanie od wyprowadzenia PD0 mikrokontrolera, do którego podłączono przycisk, skonfigurowano do reakcji na zbocze opadające. Po jego pojawieniu rdzeń wyjdzie z trybu uśpienia i nastąpi wywołanie funkcji obsługi przerwania.
Funkcja obsługi przerwania wygląda następująco:

Rdzeń wybudza się na czas około 2 sekund zaświecając cztery diody LED, gasi je i ponownie „usypia”.
Uruchomienie opisanego trybu w trakcie debugowania spowoduje przerwanie pracy debugera. Rdzeń nie pracuje, więc nie ma potrzeby poszukiwania błędów. Istnieje jednak możliwość takiej konfiguracji mikrokontrolera, że nawet w trybach obniżonego poboru mocy, połączenie debugera i mikrokontrolera nie zostanie zerwane. Do tego celu służy funkcja DBGMCU_Config().Przykładowo, jeśli wykorzystywany jest tryb uśpienia, to należy umieścić w programie linijkę:

O autorze