Forum: Mikrocontroller und Digitale Elektronik STM32L0x1 - periodischer Wakeup von Standby durch RTC mit LSE funktioniert nicht


von Robert B. (robertb)


Lesenswert?

Hallo!

Ich versuche aktuell auf einem Nucleo-32 mit STM32L011K4 einen 
periodischen Wakeup von Standby durch die RTC mit einem LSE (32.768 kHZ) 
zu realisieren.

Initial das Ganze per CubeMX, wobei ich befürchte dass das nicht 
zielführend ist. Eingeschaltet werden MSI und LSE, anschließend wird mit 
Code aus den Beispielen die RTC initialisiert und in den Standby-Mode 
gewechselt.

Grundsätzlich gilt alles auch für das STM Beispiel unter: 
STM32Cube_FW_L0_V1.10.0\Projects\STM32L011K4-Nucleo\Examples\PWR\PWR_STA 
NDBY_RTC

- Frequenz der LSE stimmt
- Wake-Up klappt, allerdings verlängert sich die in der RTC eingestellte 
Periode immer um die restlichen Zeiten beim Start-Up, z.B. im STM 
Beispiel um 5s + x.
- Warum MUSS HAL_RTCEx_SetWakeUpTimer_IT (mit "_IT" Suffix) verwendet 
werden? Zwar ist ein Interrupt-Handler implementiert, dieser wird aber 
aufgrund des Standby nach meinem Verständnis nie angesprungen. Das die 
Interrupt-Leitung auch diejenige für die Wakeup ist ist mir zumindest in 
der Doku nicht offensichtlich.
- Packt man die LSE- und RTC-Initialisierung/-Konfiguration in einen 
Code-Zweig, der nur nach einem Kaltstart ausgeführt wird, funktioniert 
das ganze nur ein mal

GEWÜNSCHTES Verhalten:
- bei Non-Standby Startup (via SB-Flag erkannt) wird LSE einmal 
eingeschaltet und die RTC als periodische Wake-Up Quelle konfiguriert
- Bei Start aus Standby kann anderer Code ausgeführt werden und 
anschließend wieder in den Standby gewechselt werden
- ... die RTC weckt wieder periodisch auf ...

Kurz: Hartes 30s Zeitraster (trotz im Run-Modus variable Laufzeiten)
1
  HAL_Init();
2
3
  /* Configure the system clock to 2 MHz */
4
  SystemClock_Config();
5
6
  /* Configure LED3 */
7
  BSP_LED_Init(LED3);
8
9
  /* Configure RTC */
10
  RTC_Config();
11
12
  /* Configure the system Power */
13
  SystemPower_Config();
14
15
  /* Check and handle if the system was resumed from StandBy mode */ 
16
  if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
17
  {
18
    /* Clear Standby flag */
19
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); 
20
  }
21
  
22
  /* Insert 5 seconds delay */
23
  HAL_Delay(5000);
24
  
25
  /* The Following Wakeup sequence is highly recommended prior to each Standby mode entry
26
    mainly  when using more than one wakeup source this is to not miss any wakeup event.
27
    - Disable all used wakeup sources,
28
    - Clear all related wakeup flags, 
29
    - Re-enable all used wakeup sources,
30
    - Enter the Standby mode.
31
  */
32
  /* Disable all used wakeup sources*/
33
  HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
34
  
35
  /* Clear all related wakeup flags */
36
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
37
  
38
  /* Re-enable all used wakeup sources*/
39
  /* ## Setting the Wake up time ############################################*/
40
  /* RTC Wakeup Interrupt Generation: 
41
    the wake-up counter is set to its maximum value to yield the longuest
42
    stand-by time to let the current reach its lowest operating point.
43
    The maximum value is 0xFFFF, corresponding to about 33 sec. when 
44
    RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16
45
46
    Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI))
47
    Wakeup Time = Wakeup Time Base * WakeUpCounter 
48
      = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSI)) * WakeUpCounter
49
      ==> WakeUpCounter = Wakeup Time / Wakeup Time Base
50
  
51
    To configure the wake up timer to 28s the WakeUpCounter is set to 0xFFFF:
52
    Wakeup Time Base = 16 /(~37.000KHz) = ~0.432 ms
53
    Wakeup Time = 0.432 ms  * WakeUpCounter
54
    Therefore, with wake-up counter =  0xFFFF  = 65,535 
55
       Wakeup Time =  0,432 ms *  65,535 = 28,311 s ~ 28 sec. */
56
  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0x0FFFF, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
57
  
58
  /* Enter the Standby mode */
59
  HAL_PWR_EnterSTANDBYMode();
60
  
61
  while (1)
62
  {
63
  }

Grüße
Robert

: Bearbeitet durch User
von Christopher J. (christopher_j23)


Lesenswert?

Im Beispiel von ST wird von einer 37kHz LSI ausgegangen aber du hast 
32,768 kHz LSE. Das könnte den Unterschied von ~5s erklären.

Robert B. schrieb:
> Das die
> Interrupt-Leitung auch diejenige für die Wakeup ist ist mir zumindest in
> der Doku nicht offensichtlich.

In Kapitel 6.3 "Low-power modes" in RM0377 in Tabelle 34 findest du 
einen groben Überblick wie du aus welchem low-power Modus wieder 
herauskommst. Details zum Verlassen des Standby-Modus findest du auf 
S.156 im Abschnitt "RTC auto-wakeup (AWU) from the Standby mode". Die 
Copy-Paste-Fehler dort darfst du getrost ignorieren. Es geht hier um den 
Standby- und nicht um den Stop-Mode. Daraus geht eindeutig hervor, dass 
ein Aufwachen aus dem Standby nur per Interrupt möglich ist (RTC-Alarm, 
-Tamper oder -Wakeup).

Robert B. schrieb:
> - Warum MUSS HAL_RTCEx_SetWakeUpTimer_IT (mit "_IT" Suffix) verwendet
> werden?

Die Funktion ohne "_IT" Suffix schaltet den Interrupt offensichtlich 
nicht scharf. Man kann dann theoretisch mit HAL_RTCEx_GetWakeUpTimer() 
den Timer pollen aber das geht eben (logischerweise) nicht aus dem 
Standby.

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
Noch kein Account? Hier anmelden.