RTC i STM32 - Hur vilka backup-register ska man välja?
Postat: 19 september 2021, 13:58:42
Min RTC är aktiv så länge Vbat är ansluten till ungefär 3V. Det betyder att trots att Vdd = 0 volt så kommer RTC:n fortfarande att ticka på. Så vill jag ha det.
Vid start hos min STM32 så initialiserar jag min RTC. Som ni ser så skriver jag över nuvarande datum och tid till 2000-01-01 00:00:00. Så vill jag inte ha det, om Vbat är ansluten till en strömkälla.
Enligt STM32 Repository för STM32F373 serien så finns det ett exempel för RTC.
Det är denna if-sats som är intressant.
Tittar man i databladet så får man egentligen ingen information om alla bitar. Det står bara "backup register".
Tittar man i koden för HAL_RTCEx_BKUPRead så står det så här:
Det betyder att jag skulle kunna avgöra om Vbat är anslutet till en strömkälla. Om fallet är JA, då behöver jag inte ändra tiden till 2000-01-01 00:00:00 vid start av min STM32.
Då är frågan:
Det finns RTC_BKP_DR0 till RTC_BKP_DR19. Vilken ska jag ha?
Med hjälp utav HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0), vad ska jag då anta vad funktionen kommer returnera tillbaka så jag kan avgöra om Vbat är aktiv eller inte?
Vid start hos min STM32 så initialiserar jag min RTC. Som ni ser så skriver jag över nuvarande datum och tid till 2000-01-01 00:00:00. Så vill jag inte ha det, om Vbat är ansluten till en strömkälla.
Kod: Markera allt
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 = 0;
sTime.Minutes = 0;
sTime.Seconds = 0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 1;
sDate.Year = 0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
/** Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 0;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
/** Enable the Alarm B
*/
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;
sAlarm.Alarm = RTC_ALARM_B;
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
Kod: Markera allt
/*##-1- Configure the RTC peripheral #######################################*/
/* Configure RTC prescaler and RTC data registers */
/* RTC configured as follows:
- Hour Format = Format 24
- Asynch Prediv = Value according to source clock
- Synch Prediv = Value according to source clock
- OutPut = Output Disable
- OutPutPolarity = High Polarity
- OutPutType = Open Drain */
RtcHandle.Instance = RTC;
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&RtcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Turn on LED1 */
BSP_LED_On(LED1);
/*##-2- Check if Data stored in BackUp register1: No Need to reconfigure RTC#*/
/* Read the Back Up Register 1 Data */
if (HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1) != 0x32F2)
{
/* Configure RTC Calendar */
RTC_CalendarConfig();
}
else
{
/* Check if the Power On Reset flag is set */
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
{
/* Turn on LED2: Power on reset occurred */
BSP_LED_On(LED2);
}
/* Check if Pin Reset flag is set */
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
{
/* Turn on LED4: External reset occurred */
BSP_LED_On(LED4);
}
/* Clear source Reset Flag */
__HAL_RCC_CLEAR_RESET_FLAGS();
}
Kod: Markera allt
/*##-2- Check if Data stored in BackUp register1: No Need to reconfigure RTC#*/
/* Read the Back Up Register 1 Data */
if (HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR1) != 0x32F2)
{
/* Configure RTC Calendar */
RTC_CalendarConfig();
}
Kod: Markera allt
/**
* @brief Reads data from the specified RTC Backup data Register.
* @param hrtc RTC handle
* @param BackupRegister RTC Backup data Register number.
* This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to
* specify the register.
* @retval Read value
*/
uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
{
uint32_t tmp = 0U;
/* Check the parameters */
assert_param(IS_RTC_BKP(BackupRegister));
tmp = (uint32_t) & (hrtc->Instance->BKP0R);
tmp += (BackupRegister * 4U);
/* Read the specified register */
return (*(__IO uint32_t *)tmp);
}
Kod: Markera allt
/* 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 */
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) == 0x32F2)
return;
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
Det finns RTC_BKP_DR0 till RTC_BKP_DR19. Vilken ska jag ha?
Med hjälp utav HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0), vad ska jag då anta vad funktionen kommer returnera tillbaka så jag kan avgöra om Vbat är aktiv eller inte?