STM32: Schlafen und Aufwachen

Gast #3439082
Lesenswert?

Hallo zusammen,

ich möchte auf dem STM32 folgendes machen:
Die Hauptschleife soll 1x pro ms ausgeführt werden. Nach Abarbeitung 
aller Prozesse soll die CPU bis zur nächsten ms schlafen gehen.
Dazu bringt Timer2 jede 1ms einen Interrupt, der die CPU aufwecken soll.

Ich hab es so implementiert (vereinfacht dargestellt):
1
volatile uint8_t aufwachen_u8;
2
main()
3
{
4
  InitTimer();
5
  NVIC_SystemLPConfig(NVIC_LP_SEVONPEND, DISABLE);
6
  while (1)
7
  {
8
    while (aufwachen_u8 == 0)
9
    {
10
      __WFE();
11
    }
12
    aufwachen_u8 = 0;
13
    Do_All_Work();
14
  }
15
}
16

17
void TIM2_IRQHandler()
18
{
19
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
20
  __SEV();
21
  aufwachen_u8 = 1;
22
}

Scheint alles zu funktionieren, aber hab ich vielleicht etwas übersehen, 
bzw. gibt es noch eine Race-Condition o.ä., die man behandeln müßte?
Gast #3439122
Lesenswert?

Es kann ein Problem geben, wenn der aufweckende Interrupt ganz genau vor 
dem Sleep-Befehl kommt. Dann müßte man wachbleiben, kann aber nicht mehr 
verhindern, daß der Sleep ausgeführt wird, und man verpaßt einen Zyklus.

Beim AVR z.B. kann man das Problem verhindern, indem man die Interrupts 
global sperrt und erst mit dem Sleep-Befehl wieder freigibt. Dies 
funktioniert, weil der SEI() mit einem Takt Verzögerung arbeitet.
Beim PIC24 z.B. gibt es einen speziellen Befehl (DISI), der die 
Interrupts global sperrt und nach x Takten automatisch wieder freigibt.
Beim STM32 hab ich eine solchen Mechanismus noch nicht gefunden, daher 
WFE() statt WFI().
Gast #3439162
Lesenswert?

Mir ist folgendes bekannt:

1. __WFI(); weckt den Controller mittels Interrupt auf
2. der STM32 geht nicht in den Standby-Modus wenn noch ein Interrupt 
ansteht


Du musst also alle IRQ-Flags explizit löschen bzw. alle anstehenden IRQs 
abarbeiten bevor du in den Standby-Modus wechseln kannst.

Beste Grüße
Gast #5084484
Lesenswert?

Hallo

ich habe das Problem, dass ich zwar die __WFI(); Anweisung ausführen 
kann, aber der Controller aus diesem Modus nicht mehr aufwacht...

Eigentlich läuft im Hintergrund ein Timer der periodische Interrupts 
auslöst, jedoch scheint er nach Ausführung der WFI Anweisung nicht mehr 
zu laufen...
Was muss ich ändern, um den Controller nach einer WFI Anweisung wieder 
durch einen Timer erwecken zu können?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren