STM32 PLL clock source doesn't work - Page 1
Forum section: electronics / general

author: mikewax
author_rank: Contributor
timestamp: June 18, 2017, 05:06:14 am
content: 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 HSI/2 * PLL multiplier. so it's supposed to be 8MHz/2 * 12 = 48MHz. so the macroRCC_CFGR_PLLMUL12determines the PLL multiplier. but when i change the 12 to a 2 as inRCC_CFGR_PLLMUL2the LED frequency does not change. the system clock frequency is the same with 2 as it is with 12.Code:#include "stm32f030x4.h"int main(void){// sysclock configurationRCC->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 has no effectRCC->CFGR &= ~RCC_CFGR_SW;RCC->CFGR |= RCC_CFGR_SW_PLL; // PLL onRCC->CFGR &= ~RCC_CFGR_HPRE;RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // sysclk (ahb) not dividedRCC->CFGR &= ~RCC_CFGR_PPRE;RCC->CFGR &= RCC_CFGR_PPRE_DIV1; // apbclk not dividedRCC->AHBENR |= RCC_AHBENR_GPIOAEN;// GPIO pin configurationpinpos = 4;GPIOA->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << (pinpos * 2));GPIOA->OSPEEDR |= ((uint32_t)(0x03) << (pinpos * 2)); // high speed 50MHzGPIOA->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos));GPIOA->OTYPER |= (uint16_t)(((uint16_t)0x00) << ((uint16_t)pinpos)); // type push/pullGPIOA->MODER &= ~(GPIO_MODER_MODER0 << (pinpos * 2));GPIOA->MODER |= (((uint32_t)0x01) << (pinpos * 2)); // mode = outputGPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pinpos * 2));GPIOA->PUPDR |= (((uint32_t)0x00) << (pinpos * 2)); // no pullwhile(1){GPIOA->ODR ^= (1 << 4); // toggle LEDfor (y = 0; y<500; y++){ // delay about 1 secondfor (x = 0; x<500; x++){}}}}

author: newbrain
author_rank: Super Contributor
timestamp: June 18, 2017, 07:17:31 am
content: I did not check in detail, but this looks very suspicious:Quote from: mikewax on June 18, 2017, 05:06:14 amThis line will clear most of the configuration you've previously set up.Edit:Some more findings:The PLL related bits in RCC_CFGR cannot be changed with PLL on, soRCC->CR |= RCC_CR_PLLON;should be moved after the PLL multiplier configuration: see ch. 7.4.2 in theRM.After switching on the PLL, one should wait for the PLLRDY bit to be set to make sure it's locked (though the system clock selection will wait for it automatically).The description of how to modify the PLL settings is in ch. 7.2.3 of the RM.In this case it should not be harmful (as all the bits you are changing have 0 reset value), but in general it would be better to read the configuration in a temporary variable, set and reset the needed bits and write it back to the configuration register. This avoids changing the configuration twice for a single operation.

author: technix
author_rank: Super Contributor
timestamp: June 21, 2017, 12:09:52 am
content: I think this code example should tell something:https://github.com/xcvista/STM32F407-Startup/blob/master/platform/src/system_stm32f4xx.cThis code is based on STM32F407, but the general procedure of STM32 clock tree manipulation should be the same.

author: newbrain
author_rank: Super Contributor
timestamp: June 21, 2017, 05:36:45 am
content: Yes, thanks.The original code does work too, once the &= is addressed and the enable PLL position corrected: checked, on a 072.Not that the OP would seem to care