cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F745 RTC Runs fast

Barber.Mark
Associate III
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

4 REPLIES 4
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

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
Up vote any posts that you find helpful, it shows what's working..
Posted on July 08, 2018 at 08:53

Hi, thanks for the comments. i configured the RTC_OUT on PC13 and measured the 1Hz which was 0.996Hz. So this has me confussed but it is working. i really do not like this situation, i like to know why things are not performaing as expected.

Posted on July 08, 2018 at 15:40

Aren't these N-1 values?

RTC->PRER=0x003f0200;

The default value is 0x007F00FF  (ie 128 * 256 = 32768)

You have 64 * 513 = 32832

32768 / 32832 = 0.99805

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