STM32F4 clock configuration using register programming
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-15 10:27 PM - edited ‎2024-07-15 10:29 PM
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:
- Select the main PLL entry clock source as HSI.
- Set PLLM = 8
- Set PLLN = 50
- Set PLLP = 2
- Enable PLL
- Wait for PLL to be locked
- Set AHB prescaler as system clock not divided
- Select PLL as the system clock
According to theoretical calculations, the system clock should be 16/8*50/2 = 50MHz.
Solved! Go to Solution.
- Labels:
-
RCC
-
STM32F4 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-16 4:31 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-15 11:36 PM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-16 12:03 AM
The scope has a 70MHz bandwidth.
About changing the bits all at once, is this right...?
RCC->PLLCFGR |= (110010 << 6);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-16 3:53 AM
> RCC->PLLCFGR |= (110010 << 6);
If it is meant to be binary, 0b110010 is correct.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-16 4:31 AM
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
