2023-04-06 08:45 AM
I am using STM32F205ZG RTC with External clock; the RTC initalization, RTC set Date function in the following lines:
int16_t RTC_HAL_init(void)
{
RTC_InitTypeDef RTC_InitStruct;
/* Enable the PWR clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Allow access to the RTC */
PWR_BackupAccessCmd(ENABLE);
/* Enable the LSE clock */
RCC_LSEConfig(RCC_LSE_ON);
while ((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET))
{ } /* wait for LSI clock to be ready*/
/* Select the RTC clock source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
/* Enable the RTC clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Configure the RTC */
RTC_InitStruct.RTC_AsynchPrediv = 127U;
RTC_InitStruct.RTC_SynchPrediv = 255U;
RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
RTC_Init(&RTC_InitStruct);
return NO_ERR;
}
int16_t RTC_set_date(uint16_t year, uint8_t month, uint8_t day)
{
RTC_DateTypeDef RTC_DateStruct;
uint16_t tempYear = 0u;
uint8_t tempMonth = 0u;
uint8_t tempDay = 0u;
RTC_DateStruct.RTC_WeekDay = day_of_week(year , month, day);
RTC_DateStruct.RTC_Date = day;
RTC_DateStruct.RTC_Month = month;
RTC_DateStruct.RTC_Year = (uint8_t)(year - 2000u);
printf( "RTC date Value is : %d : %d : %d !!\n",RTC_DateStruct.RTC_Year , RTC_DateStruct.RTC_Month, RTC_DateStruct.RTC_Date );
if (RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct)== ERROR)
{
return G_ERR;
}
return NO_ERR;
}
when I call the RTC_set_date function, it does not update the RTC date, while set time function works properly. I use the following line of the code to restart the MCU
if ((cmd =='Y') || (cmd=='y'))
{
SCB->AIRCR = 0x05FA0004;
}
in the attachment you can see the function output in different steps.
( the BSD library that I use is version V1.1.2 (05-March-2012) and BSD set date function is in below)
ErrorStatus RTC_SetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct)
{
uint32_t tmpreg = 0;
ErrorStatus status = ERROR;
/* Check the parameters */
assert_param(IS_RTC_FORMAT(RTC_Format));
if ((RTC_Format == RTC_Format_BIN) && ((RTC_DateStruct->RTC_Month & 0x10) == 0x10))
{
RTC_DateStruct->RTC_Month = (RTC_DateStruct->RTC_Month & (uint32_t)~(0x10)) + 0x0A;
}
if (RTC_Format == RTC_Format_BIN)
{
assert_param(IS_RTC_YEAR(RTC_DateStruct->RTC_Year));
assert_param(IS_RTC_MONTH(RTC_DateStruct->RTC_Month));
assert_param(IS_RTC_DATE(RTC_DateStruct->RTC_Date));
}
else
{
assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year)));
tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month);
assert_param(IS_RTC_MONTH(tmpreg));
tmpreg = RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date);
assert_param(IS_RTC_DATE(tmpreg));
}
assert_param(IS_RTC_WEEKDAY(RTC_DateStruct->RTC_WeekDay));
/* Check the input parameters format */
if (RTC_Format != RTC_Format_BIN)
{
tmpreg = ((((uint32_t)RTC_DateStruct->RTC_Year) << 16) | \
(((uint32_t)RTC_DateStruct->RTC_Month) << 8) | \
((uint32_t)RTC_DateStruct->RTC_Date) | \
(((uint32_t)RTC_DateStruct->RTC_WeekDay) << 13));
}
else
{
tmpreg = (((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Year) << 16) | \
((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Month) << 8) | \
((uint32_t)RTC_ByteToBcd2(RTC_DateStruct->RTC_Date)) | \
((uint32_t)RTC_DateStruct->RTC_WeekDay << 13));
}
/* Disable the write protection for RTC registers */
RTC->WPR = 0xCA;
RTC->WPR = 0x53;
/* Set Initialization mode */
if (RTC_EnterInitMode() == ERROR)
{
status = ERROR;
return ERROR;
}
else
{
/* Set the RTC_DR register */
RTC->DR = (uint32_t)(tmpreg & RTC_DR_RESERVED_MASK);
/* Exit Initialization mode */
RTC_ExitInitMode();
if(RTC_WaitForSynchro() == ERROR)
{
status = ERROR;
return ERROR;
}
else
{
status = SUCCESS;
}
}
/* Enable the write protection for RTC registers */
RTC->WPR = 0xFF;
return status;
}
what could be the reason for this issue?
2023-04-06 02:32 PM
How do you read the time/date?
JW
2023-04-07 12:43 AM
Thanks for the reply,
there is a delay around 2 second, between writing a date and time and reading them back according to the following piece of code.
//////
RTC_set_time(inHour,inMin,inSec);
RTC_set_date(inYear,inMonth,inDay)
delay_100ns(10u*1000u*1000u*10u);
RTC_get_date(&year, &month, &day);
RTC_get_time(&hour, &min, &sec);
runningTimer = get_run_time_ms();
printf( " date is : %d : %d : %d time is: %d : %d : %d !!\n", year, month, day, hour, min, sec);
/////
RTC read functions are mentioned below:
////
int16_t RTC_get_date(uint16_t* year, uint8_t* month, uint8_t* day)
{
RTC_DateTypeDef RTC_DateStruct;
RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct);
/* Extract year, month, and day from PRLL register */
*year = (uint16_t)(RTC_DateStruct.RTC_Year + 2000u );
*month = RTC_DateStruct.RTC_Month;
*day = RTC_DateStruct.RTC_Date;
return NO_ERR;
}
////
int16_t RTC_get_time(uint8_t *hour, uint8_t *min, uint8_t *sec)
{
RTC_TimeTypeDef RTC_TimeStruct;
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
/* Extract hour, minute, and second from PRLH register */
*hour = RTC_TimeStruct.RTC_Hours;
*min = RTC_TimeStruct.RTC_Minutes;
*sec = RTC_TimeStruct.RTC_Seconds;
return NO_ERR;
}
/////
again RTC_GetDate and RTC_GetTime are the functions developed in the BSD as I mentioned before.
/////
void RTC_GetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_RTC_FORMAT(RTC_Format));
/* Get the RTC_TR register */
tmpreg = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
/* Fill the structure fields with the read parameters */
RTC_TimeStruct->RTC_Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
RTC_TimeStruct->RTC_Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8);
RTC_TimeStruct->RTC_Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
RTC_TimeStruct->RTC_H12 = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16);
/* Check the input parameters format */
if (RTC_Format == RTC_Format_BIN)
{
/* Convert the structure parameters to Binary format */
RTC_TimeStruct->RTC_Hours = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours);
RTC_TimeStruct->RTC_Minutes = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes);
RTC_TimeStruct->RTC_Seconds = (uint8_t)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds);
}
}
///
void RTC_GetDate(uint32_t RTC_Format, RTC_DateTypeDef* RTC_DateStruct)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_RTC_FORMAT(RTC_Format));
/* Get the RTC_TR register */
tmpreg = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK);
/* Fill the structure fields with the read parameters */
RTC_DateStruct->RTC_Year = (uint8_t)((tmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16);
RTC_DateStruct->RTC_Month = (uint8_t)((tmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8);
RTC_DateStruct->RTC_Date = (uint8_t)(tmpreg & (RTC_DR_DT | RTC_DR_DU));
RTC_DateStruct->RTC_WeekDay = (uint8_t)((tmpreg & (RTC_DR_WDU)) >> 13);
/* Check the input parameters format */
if (RTC_Format == RTC_Format_BIN)
{
/* Convert the structure parameters to Binary format */
RTC_DateStruct->RTC_Year = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Year);
RTC_DateStruct->RTC_Month = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Month);
RTC_DateStruct->RTC_Date = (uint8_t)RTC_Bcd2ToByte(RTC_DateStruct->RTC_Date);
}
}
2023-04-07 10:56 AM
I'm not sure what's the mechanism of the problem you are encountering, but generally, if you read out RTC date and time, read time first, then read date.
JW
2023-04-10 10:13 PM
thanks for the advise,
at first steps I had done this also, but it did not work.
It is interesting when I monitor the RTC_DR in debug mode the code work. and it modify date as well as time. but as soon as I stop monitoring the register value it does not work!
Thanks again.
2023-04-11 03:57 AM
> at first steps I had done this also, but it did not work.
Well then it's maybe some other mechanism, maybe some which involves problem in RTC_WaitForSynchro().
You may want to avoid using libraries and resort to programming through registers. RTC may be tricky, read the RTC chapter in RM, and here and here and here. The 'F2 family RTC is slightly different from the 'F4 family so there may be some minor but important differentces, and I don't have personal experience with 'F2.
JW
2023-04-11 04:07 AM
Thanks,
You are right, some minutes a go I solve the issue.
it seems the RTC_WaitforSynchro() does not work properly!!
So I have to run it two times! while it seems the function follows the instructions in the Reference manual.!!!!
So I ma worried, If the issue is related to a potential timing issue during the RTC initialization or synchronization process, you may want to adjust your code accordingly to ensure that the RTC is properly initialized and synchronized with the system clock.
Thanks again for your help.
M.Y