fbpx

Wbudowany zegar RTC w STM32 ma tyle funkcji, że musiałem podzielić ich opis na dwa wpisy. Poprzednio pokazałem Ci bajery związane z “włamaniami”. Tym razem obudzimy śpiocha 🙂

Funkcje “budzące” RTC w STM32F4

Teraz zobaczymy sobie na dwie podobne, ale jednak różne funkcje zegara, które mogą nas obudzić, ale nie tylko nas:

  • Wake Up
  • Alarmy

Pozwól, że oprę się na płytce, którą wybrałem w poprzednim artykule. Jest to tzw. BlackPill z STM32F401 na pokładzie. Płytkę taką (lub nieco mocniejszą) możesz kupić u mnie.

stm32f411

Oprogramowanie, którego użyję to:

  • STM32CubeIDE v1.2.0
  • STM32CubeMX v5.5.0 wbudowany w IDE
  • HAL F4 v1.24.2

Będę również bazował na projekcie, który stworzyłem dla STM32F4.

WakeUp w STM32

Już sama nazwa zdradza Ci do czego to może służyć. Funkcja Wake Up służy do budzenia mikrokontrolera z trybów obniżonego poboru energii. W trybie tym nie pracują wszystkie zegary czy peryferia. Dużo zależy jaki tryb wybierzemy. Serie F mają ubogą listę możliwości, jeśli o to chodzi, ale już L-ki posiadają mnóstwo kombinacji tychże trybów.

Użycie tej funkcji w skrócie sprowadza się do ustawienia odpowiedniego timera w RTC i wejścia w tryb uśpienia. Po upłynięciu zadanego czasu nasz mikrokontroler zostanie obudzony przerwaniem, które oczywiście możemy obsłużyć chyba że to będzie “agresywny” tryb Low Power w którym nie są zapamiętywane pamięci i program ruszy od początku.

Jak to ustawić? W Cube musisz zaznaczyć, że chcesz skorzystać z Wake Up.

Pojawi Ci się w konfiguracji sekcja Wake UP, w której możesz ustawić taktowanie dedykowanego Timera oraz sam licznik.

Dla testów wybrałem taktowanie RTC podzielone na 16. Im większy dzielnik (mniejszy zegar), tym mniej energii będzie pobierał moduł Wake Up RTC podczas uśpienia MCU.

Samego licznika nie ustawiaj w Cube. To jest akurat bez sensu. Dlaczego?

Po pierwsze nie chcemy budzić się zaraz po starcie programu, gdy jeszcze nie wiemy, kiedy idziemy spać. Cube niestety ustawia od razu zegar podczas inicjalizacji i włącza jego przerwanie. Bzdura totalna.

Po drugie w funkcji inicjalizującej RTC mamy kawałek wyżej wstawiony wcześniej return, aby nie nadpisywać daty i godziny wartościami z Cube, więc kod nigdy nie dotrze do ustawienia WakeUp timera.

Kiedy i jak więc go użyć?

Ustawia się go chwilę przed wejściem w sleepa. Do tego utworzyłem specjalną funkcję Enter_LowPowerMode w sekcji użytkowanika nr 4 w której nastawiam licznik WakeUp oraz wchodzę w STOP Mode. Oparłem się na przykładzie z bibliotek HAL.

W komentarzach możesz zobaczyć, że należy wyliczyć wartość licznika, którą nastawiamy. Jest na to prosty wzór.

  • Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)), czyli bazowy tick timera WakeUp. Wybrałem dzielnik o wartości 16 oraz korzystam z wewnętrznego oscylatora, więc 16/32000 = 0,0005 s, czyli 0,5 ms.
  • Wakeup Time = Wakeup Time Base * WakeUpCounter, czyli czas, po jakim MCU ma się obudzić. Jeśli chcesz, aby robił to co około 5 sekund to wzór ten wygląda następująco
    5 = 0,0005 * WakeUpCounter 
  • WakeUpCounter = Wakeup Time / Wakeup Time Base, czyli zamieniając matematycznie strony nasze obliczenia będą wyglądały tak
    WakeUpCounter = 5 / 0,0005 = 10000 (dec) = 0x2710 (hex) i tę wartość trzeba wpisać do licznika Wake Up

Przed wejściem w STOP Mode warto zatrzymać SysTick, bo jego przerwanie również może wybudzić MCU 🙂

Funkcja HAL_PWR_EnterSTOPMode wchodzi w tryb STOP Mode z możliwością wybudzenia przerwaniem, więc RTC przerwaniem WakeUp jest w stanie wybudzić nasz MCU. To, co się dzieje zaraz za tą funkcją wykonywane jest już po obudzeniu.

Po obudzeniu wznawiam SyStick, wyłączam WakeUp i dalej działam. Testowy program akurat będzie cyklicznie usypiał i budził MCU. Na terminalu wygląda to tak.

Budzi się i zasypia. Taka rola magika. Pełny kod przykładu znajdziesz tutaj.

Alarm RTC w STM32F4

Ostatnią funkcją, którą chciałem Ci przedstawić jest Alarm. Działa on podobnie jak budzik, który nastawiasz codziennie wieczorem.

Po zrównaniu się zegara z alarmem generowane jest przerwanie. Przerwanie to oczywiście można obsłużyć lub użyć do wybudzenia mikrokontrolera z uśpienia. Jak uruchomić alarm?

Wystarczy …włączyć go w Cube 🙂

Ustawienie to powoduje przeniesienie sygnalizacji alarmu wewnątrz MCU. Można również aktywować alarm na pinie mikrokontrolera.

Oczywiście pojawi się dodatkowa konfiguracja związana z Alarmem.

Znajdziesz tutaj ustawienie nie tylko godziny i daty. Można ustawić nieco więcej kombinacji jak np. generowanie alarmu co minutę. Wszystko to za pomocą masek. Polecam się pobawić o potestować.

Jednak dużo lepiej jest ustawiać alarm z kodu i tak zrobiłem ja. Napisałem prostą funkcję, która ustawia alarm pięć sekund dalej niż aktualna godzina. Uwaga, nie działa to na dłuższą metę. Przy zmianie godziny algorytm już się sypie. Napisanie dobrze działającego algorytmu nie było moim celem 🙂

Wykorzystuję do tego osobną funkcję.

Natomiast sam alarm obsługuję ten sposób, że w jego przerwaniu ustawiam jedynie globalną flagę.

A flagą tą zajmuję się już w pętli głównej pomiędzy czytaniem aktualnej godziny z RTC.

Efekt działania?

Drzemka co 5 sekund. Jakbym widział siebie co rano 🙂

Pełny kod przykładu znajdziesz tutaj.

Podsumowanie

Poznałeś kolejne dwie funkcje wbudowanego RTC. Alarmy mogą nam przypominać o pewnych rzeczach odległych w czasie. Dzięki temu odciążamy CPU od ciągłego sprawdzania, “czy to już?”. Funkcja Wake Up może okazać się niesamowicie przydatna w urządzeniach zasilanych bateryjnie.

Pełny projekt wraz z biblioteką znajdziesz jak zwykle na moim GitHubie: LINK

Jeśli zauważyłeś jakiś błąd, nie zgadzasz się z czymś, chciałbyś coś dodać istotnego lub po prostu uważasz, że chciałbyś podyskutować na ten temat, napisz komentarz. Pamiętaj, że dyskusja ma być kulturalna i zgodna z zasadami języka polskiego.


Raz na jakiś czas wyślę Ci też e-mail z ciekawymi rzeczami które znalazłem


2 Komentarze

SaS · 12/05/2020 o 12:05

F4 maja rejestr kalibracyjny. Warto go opisać. W nocie jest wzór na wyliczenie wartości rejestru. Z precyzyjnym pomiarem częstotliwości problemu nie mam ale nie mam pomysłu, jak po wykonaniu korekty szybko zweryfikować dokładność pracy zegara? Z tego powodu, na razie, do konstrukcji dodaję trymer.
Dużo lepiej niż w F4 zrobiono korektę w DS3231. Tam są dołączane/odłączane pojemności do oscylatora, dzięki czemu, prawie on-line, można mierzyć częstotliwość oscylatora. W F4 co (jak pamiętam) 32 sekundy dodawane lub odejmowane są impulsy licznika. Z tego co wiem, nie da się wystawić sygnału minutowego na TAMPER, można 1 sekundę i chyba oscylator. pozostaje jakaś proteza programowa.

    Mateusz Salamon · 18/05/2020 o 13:58

    Jasne – można kalibrować. Tylko początkujący raczej tego nie zrobi 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *