cancel
Showing results for 
Search instead for 
Did you mean: 

RTC with HSE and STMF0

tracy
Associate II
Posted on July 10, 2014 at 15:27

I am trying to make a clock LCD display on my STM32F0. I want to use the external 8MHz crystal that is on my board. I cannot use any of the example code as none of it gives examples using the HSE. The code that I am using is below. However the code hangs in the while loop.

What am I doing wrong? 

//(1) Write access for RTC registers

//(2) Enable init phase

//(3) Wait until it is allow to modify RTC register values

//(4) set prescaler, 48/32 kHz/128 => 312 Hz, 312Hz/312 => 1Hz

//(5) New time in TR

//(6) Disable init phase

//(7) Disable write access for RTC registers

RTC->WPR = 0xCA;  //(1)

RTC->WPR = 0x53;  //(1)

RCC->BDCR |= RCC_BDCR_RTCEN;

RTC->ISR |= RTC_ISR_INIT;  //(2)

//while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF)  //(3)

//{

//add time out here for a robust application

//}

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

//RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div32);

//RTC_InitStructure.RTC_AsynchPrediv = 125 - 1; //=0x7C

//RTC_InitStructure.RTC_SynchPrediv  = 2000 - 1; // 0x7CF

RTC->PRER = 0x007C7CF;  //(4)

RTC->TR = RTC_TR_PM | 0x00000001;  //(5)

RTC->ISR &=~ RTC_ISR_INIT;  //(6)

RTC->WPR = 0xFE;  //(7)

RTC->WPR = 0x64;  //(7)

}

#stm32f0 #stm32f10x-rtc
6 REPLIES 6
Posted on July 10, 2014 at 15:59

From RM0091:

''The LSEON, LSEBYP, RTCSEL and RTCEN bits of the Backup domain control register

(RCC_BDCR) are in the Backup domain. As a result, after Reset, these bits are write-

protected and the DBP bit in the Power control register (PWR_CR) has to be set before

these can be modified.''

JW
tracy
Associate II
Posted on July 11, 2014 at 10:53

Hi,

Modified my code for initialising the RTC to the following:

PWR->CR |= PWR_CR_DBP;

//(1) Write access for RTC registers

//(2) Enable init phase

//(3) Wait until it is allow to modify RTC register values

//(4) set prescaler, 8/32 MHz/125 => 2000 Hz, 2000Hz/2000 => 1Hz

//(4) AsynchPrediv = 125 - 1; //=0x7C SynchPrediv  = 2000 - 1;  0x7CF

//(5) New time in TR

//(6) Disable init phase

//(7) Disable write access for RTC registers

RTC->WPR = 0xCA;  //(1)

RTC->WPR = 0x53;  //(1)

RCC->BDCR |= RCC_BDCR_RTCEN;

RTC->ISR |= RTC_ISR_INIT;  //(2)

while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF)  //(3)

{

//add time out here for a robust application

}

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

RTC->PRER = 0x007C7CF;  //(4)

RTC->TR = RTC_TR_PM | 0x00000001;  //(5)

RTC->ISR &=~ RTC_ISR_INIT;  //(6)

RTC->WPR = 0xFE;  //(7)

RTC->WPR = 0x64;  //(7)

However it is still not getting out of the while loop. I am not doing anything else in the software, just this and one flashing LED to help debug

Posted on July 11, 2014 at 13:30

I am not doing anything else in the software, just this and one flashing LED to help debug

Odd then, that you wouldn't post all of it to provide some complete context to your problem.

Seem to recall there being some timing nuances with the RTC due to it's relative slowness, perhaps you need to guard the unlock sequence with a little more delay.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tracy
Associate II
Posted on July 11, 2014 at 13:52

Full code listing with delay suggestion is shown below - code still hanging in the while for the RTC init.

#define STM32F051

 

#include <stdint.h>

 

#include ''stm32f0xx_rcc.h''

 

#include ''stm32f0xx_rtc.h''

 

#include ''stm32f0xx.h''

 

 

 

 

 

void initRTC(void);

 

void initLED(void);

 

void delay1(void);

 

char flag = 1;

 

 

 

 

 

void main(void) {

 

 

 

 

 

uint32_t TimeToCompute = 0, DateToCompute = 0, Time;

 

initLED();

 

initRTC();

 

for(;;){

 

if((RTC->ISR & RTC_ISR_RSF) == RTC_ISR_RSF)

 

{

 

TimeToCompute = RTC->TR; /* get time */

 

DateToCompute = RTC->DR; /* need to read date also */

 

}

 

 

 

 

 

if (flag){

 

GPIOB->ODR = 2;

 

flag = 0;

 

}

 

else{

 

GPIOB->ODR = 1;

 

flag = 1;

 

}

 

 

 

 

 

}

 

}

 

 

 

void initLED(void){

 

RCC->AHBENR |= RCC_AHBENR_GPIOBEN; //enable clock for LEDs

 

GPIOB->MODER |= GPIO_MODER_MODER0_0; //set PB0 to output

 

GPIOB->MODER |= GPIO_MODER_MODER1_0; //set PB1 to output

 

GPIOB->MODER |= GPIO_MODER_MODER2_0; //set PB2 to output

 

RCC->AHBENR |= RCC_AHBENR_GPIOBEN;

 

}

 

 

 

 

 

void initRTC(void){

 

 

 

PWR->CR |= PWR_CR_DBP; //set the DBP bit to enable RTC write acess

 

delay1();

 

//(1) Write access for RTC registers

 

//(2) Enable init phase

 

//(3) Wait until it is allow to modify RTC register values

 

//(4) set prescaler, 8/32 MHz/125 => 2000 Hz, 2000Hz/22000 => 1Hz

 

//(4) AsynchPrediv = 125 - 1; //=0x7C SynchPrediv  = 2000 - 1;  0x7CF

 

//(5) New time in TR

 

//(6) Disable init phase

 

//(7) Disable write access for RTC registers

 

RTC->WPR = 0xCA;  //(1)

 

RTC->WPR = 0x53;  //(1)

 

RCC->BDCR |= RCC_BDCR_RTCEN;

 

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

 

RTC->ISR |= RTC_ISR_INIT;  //(2)

 

while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF)  //(3)

 

{

 

//add time out here for a robust application

 

}

 

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

 

RTC->PRER = 0x007C7CF;  //(4)

 

RTC->TR = RTC_TR_PM | 0x00000001;  //(5)

 

RTC->ISR &=~ RTC_ISR_INIT;  //(6)

 

RTC->WPR = 0xFE;  //(7)

 

RTC->WPR = 0x64;  //(7)

 

 

 

}

 

void delay1(void) {

 

volatile uint32_t i = 0;

 

for(; i < 65535; i++);

 

}

Posted on July 11, 2014 at 14:40

PWR module needs to have clock enabled in RCC_APB1ENR too.

JW
tracy
Associate II
Posted on July 14, 2014 at 11:50

Hi,

Thanks I added in that line but still no luck. Code now looks like this:

#define STM32F051

#include <stdint.h>

#include ''stm32f0xx_rcc.h''

#include ''stm32f0xx_rtc.h''

#include ''stm32f0xx.h''

void initRTC(void);

void initLED(void);

void delay1(void);

char flag = 1;

void main(void) {

uint32_t TimeToCompute = 0, DateToCompute = 0, Time;

initLED();

initRTC();

for(;;){

if((RTC->ISR & RTC_ISR_RSF) == RTC_ISR_RSF)

{

TimeToCompute = RTC->TR; /* get time */

DateToCompute = RTC->DR; /* need to read date also */

}

if (flag){

GPIOB->ODR = 2;

flag = 0;

}

else{

GPIOB->ODR = 1;

flag = 1;

}

}

}

void initLED(void){

RCC->AHBENR |= RCC_AHBENR_GPIOBEN; //enable clock for LEDs

GPIOB->MODER |= GPIO_MODER_MODER0_0; //set PB0 to output

GPIOB->MODER |= GPIO_MODER_MODER1_0; //set PB1 to output

GPIOB->MODER |= GPIO_MODER_MODER2_0; //set PB2 to output

RCC->AHBENR |= RCC_AHBENR_GPIOBEN;

}

void initRTC(void){

RCC->APB1ENR |= RCC_APB1ENR_PWREN; //enable vlock for power module

PWR->CR |= PWR_CR_DBP; //set the DBP bit to enable RTC write access

delay1();

delay1();

delay1();

delay1();

//(1) Write access for RTC registers

//(2) Enable init phase

//(3) Wait until it is allow to modify RTC register values

//(4) set prescaler, 8/32 MHz/125 => 2000 Hz, 2000Hz/22000 => 1Hz

//(4) AsynchPrediv = 125 - 1; //=0x7C SynchPrediv  = 2000 - 1;  0x7CF

//(5) New time in TR

//(6) Disable init phase

//(7) Disable write access for RTC registers

RTC->WPR = 0xCA;  //(1)

RTC->WPR = 0x53;  //(1)

RCC->BDCR |= RCC_BDCR_RTCEN;

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

RTC->ISR |= RTC_ISR_INIT;  //(2)

while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF)  //(3)

{

//add time out here for a robust application

}

RCC->BDCR = RCC_BDCR_RTCSEL_HSE;

RTC->PRER = 0x007C7CF;  //(4)

RTC->TR = RTC_TR_PM | 0x00000001;  //(5)

RTC->ISR &=~ RTC_ISR_INIT;  //(6)

RTC->WPR = 0xFE;  //(7)

RTC->WPR = 0x64;  //(7)

}

void delay1(void) {

volatile uint32_t i = 0;

for(; i < 65535; i++);

}