2018-06-06 06:50 PM
Hello,
I'm using the STM32 H753 Evaluation board, and trying to set the milliseconds by using HAL_RTC_SetTime function.
However, the HAL_RTC_SetTime function does not change the milliseconds(subseconds) value.
I've read the RTC synchronization chapter in the reference manual, but I don't understand it enough though.
If I would like to set the 400 milliseconds value, should I set the 0x190(= 400 decimal) into SUBFS field in RTC_SHIFTR and set the 0x3E7(= 999 decimal) into PREDIV_S field in RTC_PRER ?
Help would be appreciated.
Thanks.
Shirane.
2018-06-07 12:08 AM
Unless you want to use some nonstandard crystal, no.
The subsecond register runs in units given by the crystal and asynchronous part of divider (i.e. 1/(fLSE/(PREDIV_A+1)), which in the normal case is equal to 1 second/(PREDIV_S+1) ) and you should set the shift register in the same units.
In the default case, i.e. PREDIV_A = 0x007F, PREDIV_S = 0x00FF, to shift by 400ms you set SUBFS to 256*0.400≈102.
JW
2018-06-13 03:16 AM
Hello,
I've tried setting SUBFS field in SHIFT register but I did't get expeced result.
I've attached my code. The below is code snippet
--------------------------------------------------------------
[main.c] <- I've added the code that set SHIFTR after calling MX_RTC_Init();
/* Initialize all configured peripherals */
MX_GPIO_Init(); MX_USART2_UART_Init(); MX_RTC_Init(); /* USER CODE BEGIN 2 */ __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc); hrtc.Instance->SHIFTR = 0x00000190;// 400msec __HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc); /* USER CODE END 2 */[rtc.c] <- set AsynchPredivas 31 andSynchPrediv as 999 in order to set the callendar clock into 1Hz.Currently I'm usingLSI(32KHz) as RTC clock.
void MX_RTC_Init(void)
{ RTC_TimeTypeDef sTime; RTC_DateTypeDef sDate;/**Initialize RTC Only
*/ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 31; hrtc.Init.SynchPrediv = 999; 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(__FILE__, __LINE__); } /* USER CODE BEGIN RTC_Init 2 *//* USER CODE END RTC_Init 2 */
/**Initialize RTC and set the Time and Date
*/ sTime.Hours = 0x13; sTime.Minutes = 0x22; sTime.Seconds = 0x30; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /* USER CODE BEGIN RTC_Init 3 */--------------------------------------------------------------
My question is that:
Thanks.
Shirane
________________ Attachments : main.c.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxVr&d=%2Fa%2F0X0000000az6%2FuL7ROgzBTPUFtaflQ8XCIP8fwLSVomvBhV.B9S88ZXg&asPdf=falsertc.c.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxVI&d=%2Fa%2F0X0000000ayx%2FtPf1npWlf4sv71iRsgEHSsyjggo0v5xurbKDNeLZu54&asPdf=false2018-06-13 05:47 AM
I've tried setting SUBFS field in SHIFT register but I did't get expeced result.
What is the expected result and what was your observation?
JW
2018-06-13 06:27 AM
Hi,
MX_RTC_Init() sets the Hours as 0x13, Minutes as 0x22 and Seconds as 0x30.
And also, my code sets 400[msec] into 'hrtc.Instance->SHIFTR'.
In main.c, printf() is called on each 100[msec], that shows the current Hours, Minutes, Seconds and Sub-seconds.
>> printf('Hours = %d, Minutes = %d, Seconds = %d, SubSeconds = %d\n', time.Hours, time.Minutes, time.Seconds, msec);
So, the expected result are:
----------------------------------------------
Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 400
Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 500
Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 600
........
----------------------------------------------
However, the current result are:
----------------------------------------------
Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 0 <- SubSeconds starts with 0.
Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 4294676 <- Strange value ?Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 4294786 <- Strange value ?Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 4294896 <- Strange value ?Hours = 13, Minutes = 22, Seconds = 30, SubSeconds = 39----------------------------------------------
Thanks.
Shirane
2018-06-13 06:36 AM
>> printf('Hours = %d, Minutes = %d, Seconds = %d, SubSeconds = %d\n', time.Hours, time.Minutes, time.Seconds, msec);
msec is from where?
Read out and print the subseconds field before and after the shift.
JW
2018-06-13 07:10 AM
>> msec is from where ?
Please check the below code.
Setting SHIFTR is performed right after MX_RTC_Init( that calls HAL_RTC_SetTime inside it.)
And, after that, HAL_RTC_GetTime is called periodically(each 100msec) and prints current time field.
-------------------------------------------
MX_RTC_Init();
/* USER CODE BEGIN 2 */ __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc); hrtc.Instance->SHIFTR = 0x00000190; // 400msec __HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc); /* USER CODE END 2 *//* Infinite loop */
/* USER CODE BEGIN WHILE */ while (1) { RTC_TimeTypeDef time; RTC_DateTypeDef date; HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); uint32_t msec = 1000 * (time.SecondFraction - time.SubSeconds) / (time.SecondFraction + 1); printf('Hours = %d, Minutes = %d, Seconds = %d, SubSeconds = %d\n', time.Hours, time.Minutes, time.Seconds, msec); HAL_Delay(100);/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
-------------------------------------------
2018-06-13 11:24 AM
This is the note to description of the RTC_SSR register in RM:
Note: SS can be larger than PREDIV_S only after a shift operation. In that case, the correct
time/date is one second less than as indicated by RTC_TR/RTC_DR.So, what happened was, that after MX_RTC_Init(), RTC_SSR == 999 as witnessed by the first printout (where thanks to the calculation formula it's printed as SubSeconds = 0). It takes some time until the correction is added from the shift register (see RTC_ISR.SHPF), but if it would happen immediately the value of RTC_SSR would be 1399. After 100ms the value of RTC_SSR is 1299 and the formula calculates (999-1299)=0xFFFFFED4; 1000*0xFFFFFED4 = 0xFFFB6C20; 0xFFFB6C20/(999+1) = 4294667 -- you have SubSeconds = 4294676, the LSI does not tick exactly at 32kHz.
JW
2018-06-15 07:05 PM
Do you mean LSI should not be used as RTC clock ?
LSE is better than LSI ?
2018-06-16 07:16 AM
LSI is a very unprecise RC oscillator, there's no point in using it for timekeeping - its purpose is to provide a very rough wakeup source in applications, where the RTC does not need to keep real time.
JW