Forum: Mikrocontroller und Digitale Elektronik STM32F103C6T6: STOP-Mode, Aufwachen per RTC


von Axel V. (axel-f)


Lesenswert?

Hallo Zusammen,

es existieren Beiträge hier zum Thema; aber die sind schon älter und 
haben mir nicht weitergeholfen. Deswegen mach ich das Thema hier nochmal 
auf.

Diese Version ohne STOP und mit RTC Alarm aller 60 sec (der über 
tick_LL() eine LED invertiert) funktioniert tadellos:
1
void tick_LL(void)
2
{
3
    if (RTC_ticks)
4
    {
5
      Lebenslicht_GPIO_Port->BSRR = (uint32_t)Lebenslicht_Pin;
6
      RTC_ticks= 0;
7
    }
8
    else
9
    {
10
      Lebenslicht_GPIO_Port->BRR = (uint32_t)Lebenslicht_Pin;
11
      RTC_ticks= 1;
12
    }
13
}
14
15
void RTC_IRQHandler(void)
16
{
17
  HAL_PWR_EnableBkUpAccess();
18
  HAL_RTC_WaitForSynchro(&hrtc);
19
  set_RTC_init();
20
  RTC->CNTL= 0;
21
  RTC->CRL&= ~RTC_FLAG_ALRAF;
22
  unset_RTC_init();
23
    tick_LL();
24
}
25
26
void set_RTC_init(void)
27
{
28
  while(!(RTC->CRL & RTC_CRL_RTOFF));
29
  RTC->CRL|= RTC_CRL_CNF;
30
}
31
32
void unset_RTC_init(void)
33
{
34
  RTC->CRL&= ~RTC_CRL_CNF;
35
  while(!(RTC->CRL & RTC_CRL_RTOFF));
36
}
37
38
39
40
int main(void)
41
{
42
  HAL_Init();
43
  SystemClock_Config();
44
45
  /* Initialize all configured peripherals */
46
  MX_GPIO_Init();
47
  MX_RTC_Init();
48
49
  set_RTC_init();
50
  RTC->ALRH= 0;
51
  RTC->ALRL= 60;
52
  RTC->CRL&= ~RTC_FLAG_ALRAF;
53
  RTC->CRH|= RTC_IT_ALRA;
54
  EXTI->IMR|= RTC_EXTI_LINE_ALARM_EVENT;
55
  EXTI->RTSR|= RTC_EXTI_LINE_ALARM_EVENT;
56
  unset_RTC_init();
57
58
  // Debuggen unter STOP
59
  HAL_DBGMCU_EnableDBGStopMode();
60
61
  while (1)
62
  {
63
64
  }
65
}
Eine andere Version, die 10 sec die LED blinken läßt, dann in STOP-Mode 
geht und nach weiteren 50 sec. vom RTC-Alarm wieder aufgeweckt wird, 
bleibt nach 2 Durchläufen im STOP bzw. irgendeinem Zwischenzustand 
hängen (lt. Stromverbrauch):
1
void RTC_IRQHandler(void)
2
{
3
  HAL_PWR_EnableBkUpAccess();
4
  HAL_RTC_WaitForSynchro(&hrtc);
5
  set_RTC_init();
6
  RTC->CNTL= 0;
7
  RTC->CRL&= ~RTC_FLAG_ALRAF;
8
  unset_RTC_init();
9
}
10
11
void set_RTC_init(void)
12
{
13
  while(!(RTC->CRL & RTC_CRL_RTOFF));
14
  RTC->CRL|= RTC_CRL_CNF;
15
}
16
17
void unset_RTC_init(void)
18
{
19
  RTC->CRL&= ~RTC_CRL_CNF;
20
  while(!(RTC->CRL & RTC_CRL_RTOFF));
21
}
22
23
int main(void)
24
{
25
  HAL_Init();
26
  SystemClock_Config();
27
  MX_RTC_Init();
28
29
  set_RTC_init();
30
  RTC->ALRH= 0;
31
  RTC->ALRL= 60;
32
  RTC->CRL&= ~RTC_FLAG_ALRAF;
33
  RTC->CRH|= RTC_IT_ALRA;
34
  EXTI->IMR|= RTC_EXTI_LINE_ALARM_EVENT;
35
  EXTI->RTSR|= RTC_EXTI_LINE_ALARM_EVENT;
36
  unset_RTC_init();
37
  zehnsek= 10;
38
39
  // Debuggen unter STOP
40
  HAL_DBGMCU_EnableDBGStopMode();
41
42
  while (1)
43
  {
44
    if (ticks)
45
    {
46
      Lebenslicht_GPIO_Port->BSRR = (uint32_t)Lebenslicht_Pin;
47
    }
48
    else
49
    {
50
      Lebenslicht_GPIO_Port->BRR = (uint32_t)Lebenslicht_Pin;
51
    }
52
    if (!zehnsek)         // wird im systick() jede Sekunde dekrementiert
53
    {
54
      Lebenslicht_GPIO_Port->BRR = (uint32_t)Lebenslicht_Pin;
55
      HAL_SuspendTick();
56
      __HAL_RCC_PWR_CLK_ENABLE();
57
//      EXTI->PR = 0xFFFFFFFF;
58
//      PWR->CR&= ~PWR_FLAG_WU;
59
      HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
60
      HAL_ResumeTick();
61
      SystemClock_Config();
62
      zehnsek= 10;
63
    }
64
  }
65
}

Auch wenn EXTI->PR = 0xFFFFFFFF; und PWR->CR&= ~PWR_FLAG_WU; ausgeführt 
werden, gibt es keine Verbesserung. Vielleicht hat jemand einen 
Beispielcode mit RTC und STOP-Mode, der funktioniert hat.

Gruß
Axel

: Verschoben durch Moderator
von Wastl (hartundweichware)


Lesenswert?

Nachdem du schon mehr als 10 Jahre hier angemeldet bist:
Was ist an dem Hinweis

"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"

nicht zu verstehen?

von Axel V. (axel-f)


Lesenswert?

Schon verstanden, aber was ist "längerer Sourcecode"? Mehr als 20 
Zeilen? Mehr als 150? Bitte in der Hilfe konkretisieren!

von Wastl (hartundweichware)


Lesenswert?

Axel V. schrieb:
> aber was ist "längerer Sourcecode"?

Länger als "eine Bildschirmseite".

Profis posten hier nur kurze Codeschnipsel im Text, alles
Andere kommt in Dateianhänge. Du darfst auch Profi sein.

von Axel V. (axel-f)


Lesenswert?

Hallo Wastl,

geht klar, ich gelobe Besserung :-)

von Axel V. (axel-f)


Lesenswert?

Letztendlich konnte ich das Problem lösen, indem ich anstatt 'WFI' ein 
'WFE' verwendet habe. Das funktioniert wunderbar! Wichtig ist (wurde 
schon mehrfach beschrieben), daß man vorneweg ein 'suspend_systick()' 
und hinterher ein 'resume_systick()' macht, da der Systick natürlich ein 
Event darstellt.

Gruß
Axel

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.