Is there a way to maintain RTC ticking without any shifts while performing a power reset?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 6:10 AM
/*UPDATE*/
It turned out that im my case the problem was in the start up routine:
There was a "Start up" project (written not by me) that was downloaded at 0 flash address and it was jumping to another address where my project was located.
I did not know that in this "Start up" project there was an RTC initialization (which prevented my RTC from running continuously).
Everything below this sentence is what I wrote before I knew where the problem is.
Good day!
I'm using RTC in a STM32F407VG controller.
I configured RTC_ALARM_A to generate an interrupt every second (this indicates when a second changes in RTC). By this interrupt, an oscilloscope and a reference 1Hz clock from another device (that is not being reset) I watch whether my RTC is ticking consistently.
With this setting it can be seen if MCU's RTC is shifting during power reset. And that's exactly what I'm observing (don't know the absolute value of the time shift, but I see that the phase of MCU's 1Hz clock output is changing randomly after power reset is done).
Can anyone tell me if there is anything that can be done to make RTC run continгously, even when a power reset is performed?
Also this things need to be mentioned:
- I do use a battery for RTC and clocks are ticking while MCU is not powered.
- I am not reinitializing the RTC periphery each time.
- Backup registers preserve their values, so no "Backup domain reset" occures.
- RTC clock is consistent during "System reset", this behavior is only seen when "Power reset" is done
Solved! Go to Solution.
- Labels:
-
RTC
-
STM32F4 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-16 6:41 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 9:20 AM
> Is there a way to maintain RTC ticking without any shifts while performing a power reset?
Yes, don't call the Cube/HAL init routine.
https://community.st.com/s/question/0D50X00009XkgBWSAZ/stm32-rtc-loses-one-second-after-each-reset and maybe a dozen of other threads here.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 10:22 PM
Here's my code
void MX_RTC_Init(void){
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = RTC_ASYNCH_DIV - 1;
hrtc.Init.SynchPrediv = RTC_SYNCH_DIV - 1;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_SECRET_DATA){/*if RTC
was not previously iinitialized*/
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
HAL_RTC_Init(&hrtc) ;
rtc_date_time_config_frst_time();
}else{/*if RTC was initialized, we only need to call HAL_RTC_MspInit*/
HAL_RTC_MspInit(&hrtc);
}
rtc_alarm_a_set_it();
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
__HAL_RCC_RTC_ENABLE();
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 1, RTC_ALARM_IRQ_PRIO);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
void rtc_alarm_a_set_it(void){
RTC_AlarmTypeDef sAlarm;
/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 0;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT_24;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_ALL;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_None;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 10:30 PM
CubeMX puts the RTC initialization there for every reset.
You need to make the change every time you generate code with CubeMX.
But if you have the backup battery, and you edit the code CubeMX generates, the RTC is reset only when you program the backup domain reset.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 10:31 PM
Thanks for your answer, but I'd seen this thread. It didn't help. As I mentioned, I'm not reinitializing RTC each time the MCU restarts.
Posting my code below.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-15 10:44 PM
Hi. I'm not using CubeMX's code, I do use a battery (I've checked the voltage on VBAT pin, is constanty 3V) and I don't see a backup domain reset taking place.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-16 3:52 AM
> if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_SECRET_DATA){/*if RTC
So, did you verify that this expression evaluates always false?
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-16 4:01 AM
Yes I did. I use a debug LED in "rtc_date_time_config_frst_time"(line 22), so I know whether it was called.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-16 4:21 AM
Also I found out that after power reset "RTC_PRER" register (the one that contains prescaler values) resets to its default value. That event takes place before executing anything in "main()". I placed a loop at the begining to ckeck that. This loop can be skipped only in debug mode, so when I enter debug mode after performing a power reset I know that nothing was previously executed in "main()".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-05-16 6:41 AM
And in the startup code, i.e. before main(), what code is there?
JW
