Skip to main content
Graduate
July 16, 2024
Solved

STM32F4 clock configuration using register programming

  • July 16, 2024
  • 2 replies
  • 2416 views

I am trying to change the system clock on my STM32F410RB using register programming. I have setup an SPI protocol to an external DAC IC which needs a minimum of 100ns (10MHz) clock period. The SPI allows for a maximum of 8MHz (fPCLK/2) at default clock settings.

I cooked up a little code but it doesn't seem to work as expected. When I probe the SCK, all I get is a constant DC type plot or a noisy output. Here is the code:

 

void set_new_system_clock(void)
{
	RCC->PLLCFGR &=~(1U<<22);

	RCC->PLLCFGR &=~(1U<<0);
	RCC->PLLCFGR &=~(1U<<1);
	RCC->PLLCFGR &=~(1U<<2);
	RCC->PLLCFGR |= (1U<<3);
	RCC->PLLCFGR &=~(1U<<4);
	RCC->PLLCFGR &=~(1U<<5);

	RCC->PLLCFGR &=~(1U<<6);
	RCC->PLLCFGR |= (1U<<7);
	RCC->PLLCFGR &=~(1U<<8);
	RCC->PLLCFGR &=~(1U<<9);
	RCC->PLLCFGR |= (1U<<10);
	RCC->PLLCFGR |= (1U<<11);
	RCC->PLLCFGR &=~(1U<<12);
	RCC->PLLCFGR &=~(1U<<13);
	RCC->PLLCFGR &=~(1U<<14);

	RCC->PLLCFGR &=~(1U<<16);
	RCC->PLLCFGR &=~(1U<<17);

	RCC->CR |= (1U<<24);
	while (!(RCC->CR & (1U<<25)));

	RCC->CFGR |= (1U<<4);
	RCC->CFGR &=~(1U<<5);
	RCC->CFGR &=~(1U<<6);
	RCC->CFGR &=~(1U<<7);

	RCC->CFGR &=~(1U<<0);
	RCC->CFGR |= (1U<<1);
}

 

 The steps I followed:

  1. Select the main PLL entry clock source as HSI. 
  2. Set PLLM = 8
  3. Set PLLN = 50
  4. Set PLLP = 2
  5. Enable PLL
  6. Wait for PLL to be locked
  7. Set AHB prescaler as system clock not divided
  8. Select PLL as the system clock

According to theoretical calculations, the system clock should be 16/8*50/2 = 50MHz.

    This topic has been closed for replies.
    Best answer by waclawek.jan

    That changing bit by bit is ehm, very suboptimal, but should work.

    However, for higher system frequencies you need to change FLASH waitstates (FLASH_ACR.LATENCY), *before* you switch clocks.

    (For even higher system frequencies you would need to change also PWR_CR.VOS, and for that enable PWR in RCC).

    JW

    2 replies

    Super User
    July 16, 2024

    I wouldn't change those values bit by bit. This causes alot of intermediate PLL states after each line.

    When you probed SCK, have you checked that you scope/LA can handle the expected frequencies?

    hth

    KnarfB

    Graduate
    July 16, 2024

    The scope has a 70MHz bandwidth.

     

    About changing the bits all at once, is this right...?

    RCC->PLLCFGR |= (110010 << 6);

    Super User
    July 16, 2024

    > RCC->PLLCFGR |= (110010 << 6);

    If it is meant to be binary, 0b110010 is correct.  

    Super User
    July 16, 2024

    That changing bit by bit is ehm, very suboptimal, but should work.

    However, for higher system frequencies you need to change FLASH waitstates (FLASH_ACR.LATENCY), *before* you switch clocks.

    (For even higher system frequencies you would need to change also PWR_CR.VOS, and for that enable PWR in RCC).

    JW