2019-04-18 02:28 AM
My code initialises the RTC using the standard CubeMX code but before setting the clock it tests for a valid year > 2018. This works perfectly and the time and date are preserved through resets of the uP.
However, it appear that either the reset or the call to HAL_RTC_Init zeroes the fractions of a second stored in the RTC registers. This can be proven by repeated resetting the processor each time withing a second which causes time to stand still.
Is there a solution to this so that the fractions of a second are preserved through resets and power cycles?
Thanks
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
int up=RTC_SMOOTHCALIB_PLUSPULSES_RESET;
int calibrate= -Option.RTC_Calibrate;
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
/* 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 = 7;
hrtc.Init.SynchPrediv = 4095;
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_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
if (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
RtcGetTime();
if(sDate.Year<18){
/* USER CODE END Check_RTC_BKUP */
/** Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
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_MONDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 0x1;
sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
}
if(Option.RTC_Calibrate>0){
up=RTC_SMOOTHCALIB_PLUSPULSES_SET;
calibrate=512-Option.RTC_Calibrate;
}
HAL_RTCEx_SetSmoothCalib(&hrtc, RTC_SMOOTHCALIB_PERIOD_32SEC, up, calibrate);
/* USER CODE END RTC_Init 2 */
}
Solved! Go to Solution.
2019-04-18 05:40 AM
Thanks that and one of the cube example programs gave the clue. Key is the statement that restores the RTC structure.
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
/* 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 = 7;
hrtc.Init.SynchPrediv = 4095;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
__HAL_RTC_RESET_HANDLE_STATE(&hrtc);
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)){
MMPrintString("Full Init\r\n");
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
}
2019-04-18 04:52 AM
I don't Cube but IMO you are not supposed to do
HAL_RTC_Init(&hrtc);
every time you reset the mcu
https://community.st.com/s/question/0D50X00009XkgBWSAZ/stm32-rtc-loses-one-second-after-each-reset
JW
2019-04-18 05:40 AM
Thanks that and one of the cube example programs gave the clue. Key is the statement that restores the RTC structure.
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
/* 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 = 7;
hrtc.Init.SynchPrediv = 4095;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
__HAL_RTC_RESET_HANDLE_STATE(&hrtc);
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)){
MMPrintString("Full Init\r\n");
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
}
2022-10-27 08:24 AM
@Community member : Thanks a lot! These two lines
__HAL_RTC_RESET_HANDLE_STATE(&hrtc);
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)){
were not included in the code I was using, obviously taken from some older reference example.
Thus, HAL_RTC_Init() was called on every startup.
Edit: Works only after reset, but not after power down... :(
2022-10-27 09:30 AM
2022-10-27 09:38 AM
Yep, I just found this (kind of official ST) answer which implements that solution:
HAL_RTC_Init() looses time · Issue #24 · STMicroelectronics/STM32CubeH7 (github.com)
Seems to work in my code. Thanks a lot, confirms it somehow.
2022-10-27 09:40 AM
Better test the RCC_BDCR configuration, especially the RTCEN bit.
2022-10-27 09:41 AM
Just found this, kind of official from ST:
HAL_RTC_Init() looses time · Issue #24 · STMicroelectronics/STM32CubeH7 (github.com)
2022-10-27 11:40 AM
Jan and I gave you a better solution than the incompetent HAL/Cube developers.
2023-01-08 07:00 AM
not everyone is very smart to understand "Better test the RCC_BDCR configuration, especially the RTCEN bit." or "It may be a better idea to use RCC_BDCR.RTCEN as basis for this test" without working example. At least I do not know how implement it. :(