Showing results for 
Search instead for 
Did you mean: 

STM32F407-Baremetal clock not working

Associate II
Hi all, I tried to configure the clock to run at 32MHz and I was using Systick to toggle the LED every 1 Sec by configuring the Systick reload value by 32Mhz -1. But, Somehow toggling is not happening for exactly 1 sec I also used a logic analyzer to check the period and it was not 1 sec. Somehow, I am not able to figure out the problem.
I selected HSE(8MHz)  and PLL as a System clock. PLLM = 2,PLLN=16,PLLP=2. AHB prescaler as 1.


#include <stdint.h>
#ifndef RCC_H_

#define RCC_H_

 #define RCC_BASE_ADDR 0x40023800 /* Base Addr of RCC */

#define FLASH_INTR 0x40023C00 /* Base of Flash Interface Register */


#define RCC_CR *(volatile uint32_t*)(RCC_BASE_ADDR + 0x00)

#define RCC_PLLCFGR *(volatile uint32_t*)(RCC_BASE_ADDR + 0x04)

#define RCC_CFGR *(volatile uint32_t*)(RCC_BASE_ADDR + 0x08)

#define RCC_APB1RSTR *(volatile uint32_t*)(RCC_BASE_ADDR + 0x20)


#define FLASH_ACR *(volatile uint32_t*)(FLASH_INTR + 0x00)


void clock_init();

void clock_init1();


#endif /* RCC_H_ */


#include "rcc.h"

void clock_init()

        FLASH_ACR |=(1<<0); /* 1 wait states */
        RCC_CR |= (1<<16); /* HSE oscillator is ON */

        while(!(RCC_CR & (1<<17))); /* wait till HSE oscillator is ready */

        RCC_PLLCFGR |= (2<<0); /* PPLM is selected */
        RCC_PLLCFGR |= (16<<6); /* PPLN is selected */
        RCC_PLLCFGR |= (0<<16); /* PPLP is selected */
        RCC_PLLCFGR |= (2<<24); /* PPLQ is selected */
        RCC_PLLCFGR |= (1<<22);  /* HSE is selected as SRC for PLL */

        RCC_CFGR |= (0<<4); /* AHB Pre-scaler */
        RCC_CFGR |= (0<<10); /* APB1 Pre-sclaer */
        RCC_CFGR |= (0<<13); /* APB2 Pre-sclaer */

        RCC_CR |= (1<<24); /* PLL is enabled */

        while(!(RCC_CR & (1<<25))); /* wait till PLL oscillator is ready */

        RCC_CFGR |= (2<<0);  /* PLL selected as system clock */

        while(!(RCC_CFGR & (2<<2))); /* wait till PLL to be clock */


#include <stdint.h>
#include "GPIO.h"
#include "rcc.h"

void delay1(void);
void Systick_Init(void);

#define SYST_CSR    *(volatile uint32_t*)(0xE000E010) /* Systick controller register */
#define SYST_RVR    *(volatile uint32_t*)(0xE000E014) /* Systick Reload Register */

int main(void)

void Systick_Init()
    /* SysTick Reload value = System clock(Hz) x Delay Desired(s) */
    Reload value = ((Clock_Speed(Hz)/Desired_Tick(Hz))-1))
    Here 1sec is required to generate systick interrupt, so the Desired Tick is 1Hz(1Sec)
    and clock speed is 16MHz
    SYST_RVR =  32000000-1; /* Reload value */
    SYST_CSR |= 0x07UL; /* Enable counter, systick interrupt, clk source as processor clk */

void SysTick_Handler()
    GPIO_ODR ^= (1<<0);

Before switching to faster clock, you need to set FLASH waitstates. [EDIT] I overlooked you do that at the beginning.

If HSE=8 and PLLM=2, input to PLL is 4MHz which is outside its maximum (2.1MHz, see PLL characteristics in datasheet).



PS. Style:

- use symbols from the CMSIS-mandated device headers, don't invent your own headers

- don't gradually OR values into registers, do that at once with one single write, either ORing all values into one single expression, or performing any calculations in a temporary value. Prefer direct writes (i.e. not read-modify-write, RMW); if you have to use RMW, again, read into temporary, perform any operation needed, and write back in one write.

Can a 24-bit down count hold 32000000-1 ??

Probably want to use the DIV8 source


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

Yes, that was a mistake. I changed the main clock to run at 8MHz and the reload value to 8000000-1 . Still, facing the same issue

Thank you.
Now, I changed the PLLM=8, PLLN=16, PPLP=2. Changed the reload value of the Systick counter to 8000000. Still facing the same issue.

> I also used a logic analyzer to check the period and it was not 1 sec.


> Still facing the same issue.

So, how much is it exactly?

If the Systick interrupt occurs once per second,  and you toggle an output pin in that interrupt, the period is *two* seconds.

If that does not explain your problem:

Read out and check/post content of relevant RCC and SYSTICK registers.

What is the primary clock source? Is it a 8MHz crystal? Is it a crystal oscillator? Or any other source?

Output HSE (or its fraction) to MCO and check frequency there.