Skip to main content
Barber.Mark
Associate III
July 6, 2018
Question

STM32F745 RTC Runs fast

  • July 6, 2018
  • 4 replies
  • 844 views
Posted on July 06, 2018 at 04:25

I have a most interesting problem i am some what baffled to resolve. i am using an STM32F745IE CPU overall a very nice device. i have setup the CPU with a 25MHz primary crystal and a 32.768KHz crystal LSE solution. The RTC seems to be running at a much faster rate roughly 4 times faster.

Setting PREDIV_A to 0x7F and PREDIV_S to 0x00ff should give me a 1Hz clock. (127+1) x (255+1) = 32768.

However when i constantly read the TR register directly, not via the shadow register,and display i see the seconds count about 4 times higher than it should be. if i increase PREVIV_S to 0x0200 it works and gives me the right time. However this concerns me, clearly i have not set some thing up correctly.

Here is the basic code set up. I am not using HAL as the performance degradation is unacceptable as the unit is almost maxed out in its operation as it is so i need lean code.

    // set up BDCR register

    // enable RCC clock for the RTC using the LSE

    RCC->BDCR|=RCC_BDCR_LSEON;            // enable the 32kHz crystal

    // wait until stable

    while((RCC->BDCR&RCC_BDCR_LSERDY)!=RCC_BDCR_LSERDY);

    // now select the correct clock source we are using the external 32kHz crystal LSE

    RCC->BDCR|=RCC_BDCR_RTCSEL_0;

    // now enable the RTC

    RCC->BDCR|=RCC_BDCR_RTCEN;

    // set the LSE drive bits for maximum drive

    RCC->BDCR|=RCC_BDCR_LSEDRV_0;

    RCC->BDCR|=RCC_BDCR_LSEDRV_1;

    // enable the power interface clock

    RCC->APB1ENR|=RCC_APB1ENR_PWREN;

    // need to write enable these bits in CR1

    PWR->CR1|=PWR_CR1_DBP;          // enable write to RTC registers

    // enable backup regulator

    PWR->CSR1|=PWR_CSR1_BRE;

    // now wait to make sure backup regulator is ready

    while((PWR->CSR1&PWR_CSR1_BRR)!=PWR_CSR1_BRR);

    // to access the RTC registers we need to write a Key to the RTC_WPR register

    RTC->WPR=0xca;

    RTC->WPR=0x53;

    // set init bit

    RTC->ISR|=RTC_ISR_INIT;         // stop calendar counter and update

    // test for INITF flag = 1 when registers can be updated

    while((RTC->ISR&RTC_ISR_INITF)!=RTC_ISR_INITF);

    // we can now update the date registers

    // setup clock and prescalers asyncon to 128 sync to 256 = 32768

    //RTC->PRER|=(127<<16);        // set async value PREDIV_A to 128

    //RTC->PRER|=255;            // set sync value PREDIV_S to 256

    RTC->PRER=0x003f0200;

    // clear init flag

    RTC->ISR&=~RTC_ISR_INIT;         // stop calendar counter and update

Any comments appreciated. 

Mark

    This topic has been closed for replies.

    4 replies

    waclawek.jan
    Super User
    July 6, 2018
    Posted on July 06, 2018 at 09:18

    Weird.

    Read back the RCC_BDCR and RTC registers you've written, and check.

    Try to reduce the drive level. Output LSE onto a MCO and measure.

    JW

    Tesla DeLorean
    Guru
    July 6, 2018
    Posted on July 06, 2018 at 14:27

    Should also be able measure internally on one of the TIM wired to LSE

    >>I am not using HAL as the performance degradation is unacceptable as the unit is almost maxed out in its operation as it is so i need lean code.

    Not sure initialization code is called frequently. Repeated RMW is not exactly efficient/lean, and not something the optimizer can fold.

    Dump out the registers after set up to confirm expectations.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..