cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 clock configuration using register programming

overbite8934
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions

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

View solution in original post

4 REPLIES 4
KnarfB
Principal III

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

The scope has a 70MHz bandwidth.

 

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

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

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

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

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