cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with Updating RTC_TR and RTC_DR registers in STM32F098:

SFons.1
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions

> 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

View solution in original post

3 REPLIES 3

> 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

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

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.