Skip to main content
SFons.1
Associate
May 2, 2020
Solved

Problem with Updating RTC_TR and RTC_DR registers in STM32F098:

  • May 2, 2020
  • 2 replies
  • 1977 views

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);
 	}
 }

This topic has been closed for replies.
Best answer by waclawek.jan

> 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

2 replies

waclawek.jan
waclawek.janBest answer
Super User
May 2, 2020

> 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

SFons.1
SFons.1Author
Associate
May 4, 2020

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.

waclawek.jan
Super User
May 2, 2020

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