STM32F107VC/Using the RTC Real Time Clock

From Teknologisk videncenter
< STM32F107VC
Revision as of 10:47, 14 June 2012 by Heth (talk | contribs) (Calibrating the RTC)
Jump to: navigation, search

Preparing for programming the STM32F107VC Real Time Clock.

//Define where in the memory the RTC start address peripheral is located
// C:\Users\Henrik thomsen\HOT\ARM\MCBSTM32C\Embed_II\usartpoll
#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

  1. 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]
  2. 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]
  3. To enable the Power voltage detector in the PWR->CR register set PVDE to 1.[3]

Checking if RTC running

  1. 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

  1. 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]
  2. To select LSE (Low Speed External XTAL) as clocksource in the RCC->BDCR register bits RTCSEL[1:0] = 01 [4]
  3. To turn on the LSE in the RCC->BDCR register bit LSEON = 1.[5]
  4. Wait in while loop (timed out for error check) for the LSE to be ready in RCC->BDCR register bit LSERDY.[6]
  5. Setting the prescaler of the RTC counter - assuming a 32,768 KHz XTAL - in register RTC->PRLH = 0 and RTC->PRLL = 0x7fff.[7]
  6. 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]
  7. 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

  1. Reference manual section 8.3.8 page 144
  2. 2.0 2.1 Reference manual section 5.4.1 page 75
  3. Reference manual section 5.4.1 page 75
  4. 4.0 4.1 Reference manual section 8.3.9 page 146
  5. Reference manual section 8.3.9 page 146
  6. Reference manual section 8.3.9 page 146
  7. Reference manual section 18.4.3 page 470
  8. Reference manual section 18.4.5 page 472
  9. Reference manual section 5.4.1 page 75
  10. Reference manual section 6 page 79