Skip to main content
Explorer II
April 27, 2024
Question

STM32F407-Baremetal clock not working

  • April 27, 2024
  • 3 replies
  • 1476 views
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.

RCC.h

#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_ */

RCC.c

#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 */

}

Main.c
#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)
{
    clock_init();
    GPIOA_Init();
    Systick_Init();
}

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);
}
    This topic has been closed for replies.

    3 replies

    Super User
    April 28, 2024

    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).

    [/EDIT]

    JW

    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.

    Explorer II
    April 28, 2024

    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.

    Graduate II
    April 28, 2024

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

    Probably want to use the DIV8 source

     

    Explorer II
    April 28, 2024

    Thanks.
    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

    Super User
    April 28, 2024

    > 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.

    JW