2020-05-02 06:51 AM
I want to use RTC module in STM32. Eventhough i try to update the date and time registers, their values are not updated. I have given my code. I would be thankful, if someone can point out what is the wrong with my procedure.
uint32_t _Time_Tens=0,_Time_Units=0,_Time_Value=0;
//Must remove
_Time_Hours=12;
_Time_Minutes=20;
_Time_Seconds = 10;
_Date_Day=20;
_Date_Month=5;
_Date_Year=2020;
//End of remove
//Configure RTC clock domain
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_DBP;
RCC->BDCR=0;
RCC->BDCR |= RCC_BDCR_BDRST;
RCC->BDCR &= ~RCC_BDCR_BDRST;
RCC->CSR &= ~RCC_CSR_LSION;
RCC->BDCR |= RCC_BDCR_LSEON;
while((RCC->BDCR & RCC_BDCR_LSERDY)!=RCC_BDCR_LSERDY);
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;//Select LSE oscillator as the RTC clock source
RCC->BDCR |= RCC_BDCR_RTCEN;//Enable RTC clock
//End of RTC clock domain configuration
//Configure RTC module
RTC->WPR = 0xCA; //Enable write access for RTC registers
RTC->WPR = 0x53; //Enable write access for RTC registers
RTC->ISR |= RTC_ISR_INIT;//Set INIT=1 tp enter initialitation mode
while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF);//wait until module enters the initialization mode
//Set Hours
_Time_Units = (uint32_t)(_Time_Hours % (uint32_t)10);
_Time_Tens = (uint32_t)(_Time_Hours/(uint32_t)10);
_Time_Value = (uint32_t)(((uint32_t)(_Time_Tens<<4) | _Time_Units)<<16);
RTC->TR = _Time_Value;
_Time_Tens=0,_Time_Units=0,_Time_Value=0;
//Set Minutes
_Time_Units = (uint32_t)(_Time_Minutes % (uint32_t)10);
_Time_Tens = (uint32_t)(_Time_Minutes/(uint32_t)10);
_Time_Value = (uint32_t)(((uint32_t)(_Time_Tens<<4) | _Time_Units)<<8);
RTC->TR |= _Time_Value;
_Time_Tens=0,_Time_Units=0,_Time_Value=0;
//Set Seconds
_Time_Units = (uint32_t)(_Time_Seconds % (uint32_t)10);
_Time_Tens = (uint32_t)(_Time_Seconds/(uint32_t)10);
_Time_Value = ((uint32_t)(_Time_Tens<<4) | _Time_Units);
RTC->TR |= _Time_Value;
_Time_Tens=0,_Time_Units=0,_Time_Value=0;
RTC->TR |= RTC_TR_PM;
RTC->ISR &= ~RTC_ISR_INIT;//Set INIT=0 t0 enter de-initialize timer
while((RTC->ISR & RTC_ISR_INITF)==RTC_ISR_INITF);//wait until module exits the initialization mode
RTC->WPR = 0xFE;
RTC->WPR = 0x64;
PWR->CR &= ~PWR_CR_DBP;
RTC->ISR &= ~RTC_ISR_RSF;
while((RTC->ISR & RTC_ISR_RSF)!=RTC_ISR_RSF);
_Time_Value = (uint32_t)RTC->TR;
_Time_Units = (uint32_t)RTC->DR;
if((_Time_Value & 0x00120000)==0x00120000){
while(1){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
HAL_Delay(500);
}
}
Solved! Go to Solution.
2020-05-02 01:09 PM
> RTC->TR |= _Time_Value;
The TR and RD registers don't behave as you would expect, they are not a "memory-like" registers, by far not.
Particularly, during initialization, they read a frozen value of the time/date at the moment when RTC_ISR.INIT has been set to 1.
This is why you cannot |= into them.
Assembly the value you want to write to them in an auxiliary variable, and perform one single write.
JW
2020-05-02 01:09 PM
> RTC->TR |= _Time_Value;
The TR and RD registers don't behave as you would expect, they are not a "memory-like" registers, by far not.
Particularly, during initialization, they read a frozen value of the time/date at the moment when RTC_ISR.INIT has been set to 1.
This is why you cannot |= into them.
Assembly the value you want to write to them in an auxiliary variable, and perform one single write.
JW
2020-05-02 01:28 PM
Alternatively, you can enable BYPSHAD
RTC->CR |= RTC_CR_BYPSHAD;
and then the TR and DR registers start to behave as you'd expect; but then you must not wait until RSF bit is set.
JW
2020-05-04 07:38 AM
Dear Jan,
Yes it worked. I had not fully understood the operation of these two shadow registers.
What i have understood now is, whatever written to these shadow registers are directly copied to their counterparts by replacing the content of them without modifying their content.
Thanks a lot for your answer.