cancel
Showing results for 
Search instead for 
Did you mean: 

How to wake-up on time in time with RTC ?

duongtomho
Associate II

Hi eveyone,

I have a problem with RTC wake up. I use LSE 32.768kHz.

I run example from manufacturer to wake up MCU from Stand by mode very 1min, 2mins. Everything work okay.

But, When I put delay 10s and HAL_PWR_EnterSTANDBYMode(); into while(1). Everything is not okay.

The RTC does not wake up on time, when I delay 10s it will lack of 10s, when I delay 20s it lack of 20s. I try to do it many times.

How can I wake-up mcu on time in time I set?

Thank you for any help.

int main(void)
{
  HAL_Init();
 
  /* Configure LED3 */
  BSP_LED_Init(LED3);
 
  /* Configure the system clock to 2 MHz */
  SystemClock_Config();
 
  /* Configure the system power */
  SystemPower_Config();
 
  /* Check and handle if the system was resumed from StandBy mode */ 
  if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
  {
    /* Clear Standby flag */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); 
  }
 
  /* Disable Wakeup Counter */
  HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
 
  /*## Setting the Wake up time ############################################*/
  /*  RTC Wakeup Interrupt Generation:
      Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI))
      Wakeup Time = Wakeup Time Base * WakeUpCounter 
                  = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)) * WakeUpCounter
      ==> WakeUpCounter = Wakeup Time / Wakeup Time Base
 
      To configure the wake up timer to 4s the WakeUpCounter is set to 0x1FFF:
        RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16 
        Wakeup Time Base = 16 /(~39.000KHz) = ~0,410 ms
        Wakeup Time = ~4s = 0,410ms  * WakeUpCounter
        ==> WakeUpCounter = ~4s/0,410ms = 9750 = 0x2616 */
  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0x2616, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
  
  /* Insert 5 seconds delay */
  HAL_Delay(5000);
  
  /* Clear all related wakeup flags */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
 
 
  while (1)
  {
	HAL_Delay(10000);
 
	/* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
	HAL_PWR_EnterSTANDBYMode();
  }
}

1 ACCEPTED SOLUTION

Accepted Solutions
Mohamed Aymen HZAMI
ST Employee

Hello,

Why you do not set the wake up time by setting the wake counter in the HAL_RTCEx_SetWakeUpTimer_IT function.

Instead of adding the "HAL_Delay" function, you can simply customize your wake up time like this:

- For example if you want to waking-up the MCU after 10 seconds:

  • Wakeup Time Base = 16 (RTC Clock Div) /(39.000KHz) = 0,410 ms
  • Wakeup Time = 10s = 0,410ms * WakeUpCounter
    • WakeUpCounter = 10s /0,410ms = 24 390= 0x5F46

You need just to calculate the value that you want to set.

Best Regards,

Mohamed Aymen.

View solution in original post

5 REPLIES 5
Mohamed Aymen HZAMI
ST Employee

Hello,

I think that you are working with an STM32L4 device ?

Why you put the HAL_PWR_EnterSTANDBYMode() in the while(1) loop ?

Best Regards,

Mohamed Aymen.

duongtomho
Associate II

Hello mohamed-aymen.hzami,

I use STM32L151

I put HAL_PWR_EnterSTANDBYMode(), because I want to run my program in while(1). After that I put microcontroller into stanby mode, and it will wake up after 1min

I try to use HAL_RTC_DeInit(&hrtc); after call HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, timeMin, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); and before call  HAL_PWR_EnterSTANDBYMode(), I call HAL_RTC_DeInit(&hrtc);

My program run and wake up on time. But In the first run, it wake-up immediately, after that it run true. I don't know why.

Below its my code. Thanks for your attention.

int main(void)
{
  HAL_Init();
 
  /* Configure LED3 */
  BSP_LED_Init(LED3);
 
  /* Configure the system clock to 2 MHz */
  SystemClock_Config();
 
  /* Configure the system power */
  SystemPower_Config();
 
  /* Check and handle if the system was resumed from StandBy mode */ 
  if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
  {
    /* Clear Standby flag */
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); 
  }
 
  /* Disable Wakeup Counter */
  HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
 
  /*## Setting the Wake up time ############################################*/
  /*  RTC Wakeup Interrupt Generation:
      Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI))
      Wakeup Time = Wakeup Time Base * WakeUpCounter 
                  = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)) * WakeUpCounter
      ==> WakeUpCounter = Wakeup Time / Wakeup Time Base
 
      To configure the wake up timer to 4s the WakeUpCounter is set to 0x1FFF:
        RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16 
        Wakeup Time Base = 16 /(~39.000KHz) = ~0,410 ms
        Wakeup Time = ~4s = 0,410ms  * WakeUpCounter
        ==> WakeUpCounter = ~4s/0,410ms = 9750 = 0x2616 */
  HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0x2616, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
  
  /* Insert 5 seconds delay */
  HAL_Delay(5000);
  
  /* Clear all related wakeup flags */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
HAL_RTC_DeInit(&hrtc);
 
 
  while (1)
  {
	HAL_Delay(10000);
 
	/* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
        HAL_RTC_Init(&hrtc);
 
	HAL_PWR_EnterSTANDBYMode();
  }
}

Mohamed Aymen HZAMI
ST Employee

Hello,

Why you do not set the wake up time by setting the wake counter in the HAL_RTCEx_SetWakeUpTimer_IT function.

Instead of adding the "HAL_Delay" function, you can simply customize your wake up time like this:

- For example if you want to waking-up the MCU after 10 seconds:

  • Wakeup Time Base = 16 (RTC Clock Div) /(39.000KHz) = 0,410 ms
  • Wakeup Time = 10s = 0,410ms * WakeUpCounter
    • WakeUpCounter = 10s /0,410ms = 24 390= 0x5F46

You need just to calculate the value that you want to set.

Best Regards,

Mohamed Aymen.

@Mohamed Aymen HZAMI 

If I want MCU to go to standby/stop mode for 10 hours, the counter value should be

  • WakeUpCounter = 36000s/0.41s = 87804.

However, it does not work. In my test, MCU wakes up just a few seconds nor matter how big WakeUpCounter is assigned.

Hello @HDaji.1 

For the WakeUpCounter you have to take into account the counter deepth and the clock.

If you use RTC_WAKEUPCLOCK_RTCCLK_DIV2 as the clock, then you'll just have 2^16 * (2/32000) ≈ 4s, 32000 here is my origine clock (32K LSI), si it can change according to your situation.

But if you use RTC_WAKEUPCLOCK_CK_SPRE_16BITS (1Hz clock), then you can last 2^16 / (1Hz * 3600s)  18.2 hours.

And if you want to go even further, you can use RTC_WAKEUPCLOCK_CK_SPRE_17BITS (0.5Hz), and you will be able to last 2^16 / (0.5Hz * 3600s)   36.4 Hours.

So, if you want to stop for 10 hours, you can use :

 

HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 36000, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 36000);