Maker Pro
Maker Pro

STM32 PLL clock source doesn't work

hello i wonder if any STM engineers can see what's wrong with my code. it's an STM32F030F4P6 chip. all it does is blink an LED. the problem is i set the system clock as sysclock = HSI/2 * PLL multiplier. so it's supposed to be 8MHz/2 * 12 = 48MHz. and the macro RCC_CFGR_PLLMUL12 determines the PLL multiplier. but when i change the 12 to a 2 as in RCC_CFGR_PLLMUL2 the LED frequency does not change. the system clock frequency is the same with 2 as it is with 12. i don't know what i'm doing wrong here.
Code:
#include "stm32f030x4.h"

int main(void)
{
 // sysclock configuration
  RCC->CR |= RCC_CR_HSION;
  RCC->CR |= RCC_CR_PLLON;
  RCC->CFGR &= ~RCC_CFGR_PLLSRC;
  RCC->CFGR |= RCC_CFGR_PLLSRC_HSI_DIV2;
  RCC->CFGR &= ~RCC_CFGR_PLLMUL;
  RCC->CFGR |= RCC_CFGR_PLLMUL12; // <--- changing the multiplier does not change LED frequency
  RCC->CFGR &= ~RCC_CFGR_SW;
  RCC->CFGR |= RCC_CFGR_SW_PLL; // PLL on
  RCC->CFGR &= ~RCC_CFGR_HPRE;
  RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // sysclk (ahb) not divided
  RCC->CFGR &= ~RCC_CFGR_PPRE;
  RCC->CFGR &= RCC_CFGR_PPRE_DIV1; // apbclk not divided
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
 
 // GPIO pin configuration
  pinpos = 4;
  GPIOA->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << (pinpos * 2));
  GPIOA->OSPEEDR |= ((uint32_t)(0x03) << (pinpos * 2)); // high speed 50MHz
  GPIOA->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));
  GPIOA->OTYPER |= (uint16_t)(((uint16_t)0x00) << ((uint16_t)pinpos)); // type push/pull
  GPIOA->MODER  &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
  GPIOA->MODER |= (((uint32_t)0x01) << (pinpos * 2)); // mode = output
  GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));
  GPIOA->PUPDR |= (((uint32_t)0x00) << (pinpos * 2)); // no pull

    while(1){
    GPIOA->ODR ^= (1 << 4);     // toggle LED
    for (y = 0; y<500; y++){        // delay about 1 second
      for (x = 0; x<500; x++){}
    }
  }
}
 

Harald Kapp

Moderator
Moderator
I'm not familiar with the STM, but it seems you PLL initialization sequence doesn't follow these steps from the manual:
To modify the PLL configuration, proceed as follows:
1. Disable the PLL by setting PLLON to 0.
2. Wait until PLLRDY is cleared. The PLL is now fully stopped.
3. Change the desired parameter.
4. Enable the PLL again by setting PLLON to 1.
5. Wait until PLLRDY is se
I do neither see that you disable the PLL nor that you wait for PLLRDY.
 
Top