STM32F107VC/Using the RTC Real Time Clock
From Teknologisk videncenter
								
												
				Preparing for programming the STM32F107VC Real Time Clock.
//Define where in the memory the RTC start address peripheral is located
#define RTC_BASE         0x40002800 // See reference manual page 52
 
//Define the RTC register map. See reference manual section 18.4.7 page 474
unsigned int volatile * const rtc_crh  = (unsigned int *) (RTC_BASE + 0x0); //PARANTESER
unsigned int volatile * const rtc_crl  = (unsigned int *) (RTC_BASE + 0x4);
unsigned int volatile * const rtc_prlh = (unsigned int *) (RTC_BASE + 0x8);
unsigned int volatile * const rtc_prll = (unsigned int *) (RTC_BASE + 0xc);
unsigned int volatile * const rtc_divh = (unsigned int *) (RTC_BASE + 0x10);
unsigned int volatile * const rtc_divl = (unsigned int *) (RTC_BASE + 0x14);
unsigned int volatile * const rtc_cnth = (unsigned int *) (RTC_BASE + 0x18);
unsigned int volatile * const rtc_cntl = (unsigned int *) (RTC_BASE + 0x1c);
unsigned int volatile * const rtc_alrh = (unsigned int *) (RTC_BASE + 0x20);
unsigned int volatile * const rtc_alrl = (unsigned int *) (RTC_BASE + 0x24);
//Define where in the memory the RCC start address peripheral is located
#define RCCBASE         0x40021000
//unsigned int volatile * const rcc_apb1en = (unsigned int *) 0x4002101c;
unsigned int volatile * const rcc_apb1en = (unsigned int *) (RCCBASE + 0x1c);
unsigned int volatile * const rcc_bdcr = (unsigned int *) (RCCBASE + 0x20);
//Define where in the memory the PWR start address peripheral is located
#define PWR_BASE         0x40007000
unsigned int volatile * const pwr_cr = (unsigned  int *) PWR_BASE + 0x0;
void rtcinit(void) {
	
	int i;
	printf("Initializing RTC\n");
	*rcc_apb1en |= 1 << 27;  	// enable BKP unit
	*rcc_apb1en |= 1 << 28; 	// enable PWR unit
	*pwr_cr      |= 0x3 << 5; 	// PLS[2:0] = 011
	*pwr_cr		|= 1 << 4;		// Enable Power voltage detector
	if ( (*rcc_bdcr &= 1 << 15) == 0  ) { // If RTC not running
		// Programming the RTC
			*pwr_cr 		|= 1 << 8; 		// Disable Write protect
			*rcc_bdcr	|= 0x1 << 8;	// Select external XTAL - LSE
			*rcc_bdcr	|= 1;		 	// LSEON
			*rcc_bdcr	|= 1 << 15;		// RTC on
			for (i=0; (i < 10000000) || ( (*rcc_bdcr & !(1 << 1) ) == 0 ); i++)// Wait LSE ready
			if (i == 10000000) {
				printf("ERROR: RTC never ready\n");
			}
			*rtc_prlh = 0x7fff;			// Setting prescaler to 32767 (0x7fff)
			//Set correct time here
			*pwr_cr &= !(1 << 15);	// Enable write protect
	}
}
Initializing the RTC
- Goals
 - Enabling the RTC
 - One seconds TICK
 - No interrupts enable
 - Initializing second counter to present time (Epoch 1/1-1970 00:00:00)
 - Using external XTAL
 - Write protect against accidental writes
 
Enabling the RTC
Power on Init
- To enable the RTC it is necessary to enable the Power interface in the RCC->APB1ENR register by setting the PWREN bit to 1. [1]
 - To select the voltage threshold when the RTC switch to battery power. E2PROM minimum operating voltage is 2.5 V. In the PWR->CR register set PLS[2:0] to 011[2]
 - To enable the Power voltage detector in the PWR->CR register set PVDE to 1.[3]
 
Checking if RTC running
- In the RCC->BDCR Register check if the RTCEN bit is 1 and the LSEON is 1 and LSERDY is 1 - If not the RTC is not running and need programming. (See below)[4]
 
Programming the RTC
- To disable write protection to the Backup domain control register - enabling configuration of the RTC in the PWR->CR register setting the DBP bit to 1. [2]
 - To select LSE (Low Speed External XTAL) as clocksource in the RCC->BDCR register bits RTCSEL[1:0] = 01 [4]
 - To turn on the LSE in the RCC->BDCR register bit LSEON = 1.[5]
 - Wait in while loop (timed out for error check) for the LSE to be ready in RCC->BDCR register bit LSERDY.[6]
 - Setting the prescaler of the RTC counter - assuming a 32,768 KHz XTAL - in register RTC->PRLH = 0 and RTC->PRLL = 0x7fff.[7]
 - Setting the Counter to the current time in seconds since epoch. (Set the RTC->CNTH before the RTC->CNTL avoiding RTC->CNTL = 0xffff incrementing RTC->CNTH before writing to it.) [8]
 - To enable write protection to the Backup domain control register - disableing configuration of the RTC in the PWR->CR register setting the DBP bit to 0. [9]
 
Calibrating the RTC
IN the Backup Register[10] See RTC Calibration Application Note
Links
References
- ↑ Reference manual section 8.3.8 page 144
 - ↑ 2.0 2.1 Reference manual section 5.4.1 page 75
 - ↑ Reference manual section 5.4.1 page 75
 - ↑ 4.0 4.1 Reference manual section 8.3.9 page 146
 - ↑ Reference manual section 8.3.9 page 146
 - ↑ Reference manual section 8.3.9 page 146
 - ↑ Reference manual section 18.4.3 page 470
 - ↑ Reference manual section 18.4.5 page 472
 - ↑ Reference manual section 5.4.1 page 75
 - ↑ Reference manual section 6 page 79