3

I am using the stm32F0xx series and am trying to get the RTC to work. I have an external 8MHz crystal connected and using PLL to create a sysclk of 48MHz. Obviously I would like to use this clock with the RTC. I have tried the following:

//(1) Write access for RTC registers
    //(2) Enable init phase
    //(3) Wait until it is allow to modify RTC register values
    //(4) set prescaler, 
    //(5) New time in TR
    //(6) Disable init phase
    //(7) Disable write access for RTC registers
    RTC->WPR = 0xCA;  //(1)
    RTC->WPR = 0x53;  //(1)
    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 = 0x007C2E7C;  //(4)
    RTC->TR = RTC_TR_PM | 0x00000001;  //(5)
    RTC->ISR &=~ RTC_ISR_INIT;  //(6)
    RTC->WPR = 0xFE;  //(7)
    RTC->WPR = 0x64;  //(7)

In the main loop there is an infinite for that turns two led's on and off. Without the RTC config this works fine but as soon as I add in the code above it stops working.

If I do this then the rest of the code breaks. Can I use HSE and if so am I using the prescalar correctly?

x29a
  • 1,761
  • 1
  • 24
  • 43
TracyB
  • 31
  • 1
  • 2
  • Why don't you use the ST standard library? An API to use the RTC is already implemented there. – Étienne Jul 07 '14 at 19:10
  • I must admit I am not a big fan of the ST library because you have two levels of abstraction. The first being the structs and the second all the functions. Also the ST library only has options to use the LSE and LSI clocks. Not the HSI clock which I need. – TracyB Jul 08 '14 at 12:54
  • You said you wanted to use the external crystal, right? This is HSE, not HSI, and this is supported by the ST library. (search for RCC_RTCCLKSource_HSE_Div128). – Étienne Jul 08 '14 at 14:14
  • Apologies I meant HSE not HSI. I only have RCC_RTCCLKSource_HSE_Div32. This is just a #define for this: RCC_BDCR_RTCSEL_HSE which is what I am doing in the line RCC->BDCR = RCC_BDCR_RTCSEL_HSE – TracyB Jul 08 '14 at 14:26
  • Oh sorry I checked the STM32F1 library instead of the STM32F0. – Étienne Jul 08 '14 at 15:01
  • So my theory on the clock is the following. I have an 8MHz external crystal that is being converted by eclipse in the backend to a 48MHz clock. I made the assumption that by using HSE_Div32 that meant 48MHz /32 was the clock for the RTC. Then to get down to a 1Hz signal I set the asyncronous prescalar divider to (125-1) and the syncronous prescalar to (12000-1) which will further divide the signal by 125 and then 12000 respectively. What is odd is that nothing in the code works. I would have assumed that if I had got it wrong the clock would just be inaccurate – TracyB Jul 08 '14 at 15:44
  • HSE_Div32 should mean 8 MHz/32, not 48 MHz/32. (48MHz is the PLL output). – Étienne Jul 08 '14 at 16:20
  • Thanks for that - I have corrected the prescalar. I have debugged further and it seems that the micro is hanging on the following line : while ((RTC->ISR & RTC_ISR_INITF) != RTC_ISR_INITF) //(3) { //add time out here for a robust application } – TracyB Jul 10 '14 at 12:56

1 Answers1

3

This example from actual working code for using HSE for RTC at STM32f429. It uses STM HAL software library, but can gives you a clue to solve.

Please note, that HSE already must be configured and used as frequency source before this code.

Remark: when reading, you should read not just time but also date. i.e.: HAL_RTC_GetTime(&RTChandle, &RTCtime, FORMAT_BIN); //first HAL_RTC_GetDate(&RTChandle, &RTCdate, FORMAT_BIN); //second, even if you dont required otherwise registers stay frozen (in this case you see ticks only under debugger but not in real run, because debug reads both registers)

// enable access to rtc register
HAL_PWR_EnableBkUpAccess();
// 1. 8Mhz oscillator (Source crystal! Not after PLL!) div by 8 = 1 Mhz
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_HSE_DIV8);
RTChandle.Instance = RTC;
RTChandle.Init.HourFormat = RTC_HOURFORMAT_24;
// 2. (1 Mhz / 125) = 7999 ticks per second
RTChandle.Init.AsynchPrediv = 125 - 1;
RTChandle.Init.SynchPrediv = 8000 - 1;
RTChandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RTChandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTChandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

// do init
HAL_RTC_Init(&RTChandle);
// enable hardware
__HAL_RCC_RTC_ENABLE();
FlyTekDev
  • 31
  • 4