cancel
Showing results for 
Search instead for 
Did you mean: 

STANDBY and SLEEP Modes using RTC

AnanyaRavi29
Associate II

Hello,
I am trying to use the SLEEP and STANDBY modes with the RTC. I want the device to go to sleep/standby mode for 10 seconds and wake up after the 10 seconds are done. I have tried it with an interrupt using UART and Button and both the modes are working fine.But with RTC I am facing an issue.
Can anyone pls help with this query of mine?

Thanking you.

6 REPLIES 6
Sarra.S
ST Employee

Hello @AnanyaRavi29

See STM32CubeL1/Projects/NUCLEO-L152RE/Examples/PWR/PWR_STANDBY_RTC at master · STMicroelectronics/STM32CubeL1 · GitHub

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Its working for STANDBY Mode.But for SLEEP Mode I am unable to get the core to wake up pls.

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	      HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	      sprintf(date, "Date: %02d.%02d.%02d\t", sDate.Date, sDate.Month, sDate.Year);
	      sprintf(time, "Time: %02d:%02d:%02d\r\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
	      HAL_UART_Transmit(&huart2, (uint8_t *)date, strlen(date), HAL_MAX_DELAY);
	      HAL_UART_Transmit(&huart2, (uint8_t *)time, strlen(time), HAL_MAX_DELAY);

	      // Configure RTC alarm to trigger after 10 seconds
	      RTC_AlarmTypeDef sAlarm;
	      sAlarm.AlarmTime.Hours = 0;
	      sAlarm.AlarmTime.Minutes = 0;
	      sAlarm.AlarmTime.Seconds = 10;
	      sAlarm.Alarm = RTC_ALARM_A;
	      if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
	      {
	        Error_Handler();
	      }

	      // Enter Sleep mode
	      HAL_UART_Transmit(&huart2, (uint8_t *)"MCU is going to sleep...\r\n", strlen("MCU is going to sleep...\r\n"), HAL_MAX_DELAY);
	      HAL_SuspendTick(); // Suspend HAL tick
	      HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE);

	      // MCU wakes up here

	      // Resume operations after wake-up
	      //SystemClock_Config(); // Restore system clock settings
	      HAL_ResumeTick();     // Resume HAL tick

	      HAL_UART_Transmit(&huart2, (uint8_t *)"MCU woke up from sleep mode\r\n", strlen("MCU woke up from sleep mode\r\n"), HAL_MAX_DELAY);

	      // Delay to avoid immediate sleep cycle
	      HAL_Delay(1000);

...

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

	  // Print current time and date after wake-up
	  HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
	  HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BIN);
	  sprintf(date, "Date: %02d.%02d.%02d\t", sDate.Date, sDate.Month, sDate.Year);
	  sprintf(time, "Time: %02d:%02d:%02d\r\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
	  HAL_UART_Transmit(&huart2, (uint8_t *)date, strlen(date), HAL_MAX_DELAY);
	  HAL_UART_Transmit(&huart2, (uint8_t *)time, strlen(time), HAL_MAX_DELAY);
}

This is the code I wrote.Can you pls tell where I went wrong?
 

Hello @AnanyaRavi29 

In Sleep mode, only certain interrupts can wake up the microcontroller, make sure that the RTC wakeup interrupt is enabled

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

So instead of Alarm I have to use Wakeup Interrupt pls?

try HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

Use WFI instead of WFE if you are not using an actual interrupt handler

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have tried that pls.

Its still not working.

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  // Print current time and date
	      HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
	      HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
	      sprintf(date, "Date: %02d.%02d.%02d\t", sDate.Date, sDate.Month, sDate.Year);
	      sprintf(time, "Time: %02d:%02d:%02d\r\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
	      HAL_UART_Transmit(&huart2, (uint8_t *)date, strlen(date), HAL_MAX_DELAY);
	      HAL_UART_Transmit(&huart2, (uint8_t *)time, strlen(time), HAL_MAX_DELAY);

	      // Configure RTC Wakeup Timer to trigger after 10 seconds
	      HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x5F86 , RTC_WAKEUPCLOCK_RTCCLK_DIV16);

	      // Enter Sleep mode using WFE
	      HAL_UART_Transmit(&huart2, (uint8_t *)"MCU is going to sleep...\r\n", strlen("MCU is going to sleep...\r\n"), HAL_MAX_DELAY);
	      HAL_SuspendTick(); // Suspend HAL tick
	      HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);

	      // MCU wakes up here

	      // Resume operations after wake-up
	      SystemClock_Config(); // Restore system clock settings
	      HAL_ResumeTick();     // Resume HAL tick

	      HAL_UART_Transmit(&huart2, (uint8_t *)"MCU woke up from sleep mode\r\n", strlen("MCU woke up from sleep mode\r\n"), HAL_MAX_DELAY);

	      // Delay to avoid immediate sleep cycle
	      HAL_Delay(1000);


  }



void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
    // Handle RTC Wakeup event
    // Example: Toggle an LED to indicate wake-up
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);

    // Print current time and date after wake-up (optional)
    RTC_DateTypeDef sDate;
    RTC_TimeTypeDef sTime;
    HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(hrtc, &sDate, RTC_FORMAT_BIN);
    char time[20];
    sprintf(time, "%02d:%02d:%02d\r\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
    HAL_UART_Transmit(&huart2, (uint8_t *)time, strlen(time), HAL_MAX_DELAY);
}


static void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  RTC_AlarmTypeDef sAlarm = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */

  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */

  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x5;
  sTime.Minutes = 0x50;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
  sDate.Month = RTC_MONTH_JUNE;
  sDate.Date = 0x20;
  sDate.Year = 0x24;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }

  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Seconds = 0x10;
  sAlarm.AlarmTime.SubSeconds = 0x0;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
                              |RTC_ALARMMASK_MINUTES;
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 0x1;
  sAlarm.Alarm = RTC_ALARM_A;
  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }

  /** Enable the WakeUp
  */
  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */

  /* USER CODE END RTC_Init 2 */

}