2014-07-10 06:27 AM
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-rtc2014-07-10 06:59 AM
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.'' JW2014-07-11 01:53 AM
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 debug2014-07-11 04:30 AM
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.2014-07-11 04:52 AM
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++);
}
2014-07-11 05:40 AM
PWR module needs to have clock enabled in RCC_APB1ENR too.
JW2014-07-14 02:50 AM
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++);}