Help me set clock configuration on STM32 - Keil - Page 1
Forum section: electronics / general

author: ppTRN
author_rank: Regular Contributor
timestamp: November 25, 2024, 08:09:31 pm
content: Setting the clock tree on CubeIDE is very easy. (MCU: STM32F303K8)I am now starting programming with Keil and I do not understand how to do it. The clock configuration is in the SystemCoreClockUpdate function (it is, right?), that needs to be called if I want to update the clock config from the initial default state.Code:void SystemCoreClockUpdate (void){uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;/* Get SYSCLK source -------------------------------------------------------*/tmp = RCC->CFGR & RCC_CFGR_SWS;switch (tmp){case RCC_CFGR_SWS_HSI: /* HSI used as system clock */SystemCoreClock = HSI_VALUE;break;case RCC_CFGR_SWS_HSE: /* HSE used as system clock */SystemCoreClock = HSE_VALUE;break;case RCC_CFGR_SWS_PLL: /* PLL used as system clock *//* Get PLL clock source and multiplication factor ----------------------*/pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;pllmull = ( pllmull >> 18) + 2;#if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx)predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV){/* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;}else{/* HSI oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull;}#elseif (pllsource == RCC_CFGR_PLLSRC_HSI_DIV2){/* HSI oscillator clock divided by 2 selected as PLL clock entry */SystemCoreClock = (HSI_VALUE >> 1) * pllmull;}else{predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;/* HSE oscillator clock selected as PREDIV1 clock entry */SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;}#endif /* STM32F302xE || STM32F303xE || STM32F398xx */break;default: /* HSI used as system clock */SystemCoreClock = HSI_VALUE;break;}/* Compute HCLK clock frequency ----------------*//* Get HCLK prescaler */tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];/* HCLK clock frequency */SystemCoreClock >>= tmp;}Here's what I understood about this function:1. It retrives the system clock source2. Based on that it writes it into SystemCoreClock (what is that??). The possible sources includes the PLL outputThen there are some more assigns to SystemCoreClock, but I do not understand them.I think I first need to set some registers in order to actually set the PLL values and configure the clock tree, then calling the SystemCoreClockUpdate, and it takes care of everithing.Said registers should be all RCC registers listed on the reference manual (RCC_CR, CC_CFGR, RCC_CIR).Should I set these registers on the Reset_handler before calling the SystemInit function?Sorry if this sounds trivial, but I never did this and testing the resoults of blind tests can be really hard.

author: westfw
author_rank: Super Contributor
timestamp: November 26, 2024, 12:44:59 am
content: QuoteYes, that's all it does - retrieve and save. A bunch of other library functions then use SystemCoreClock to do things like calculate baud rate divisors... AFAICT, you're supposed to set up the clock "manually" by manipulating its registers, and then SystemCoreClockUpdate() is used to propagate that info to the rest of the libraries. (Which always seemed like a weird way to do it, to me.)

author: rhodges
author_rank: Frequent Contributor
timestamp: November 26, 2024, 01:02:36 am
content: When I started with STM32F103 and STM32F030, I just went with the max 72 and 48 mhz. But moving to the 32F407, I decided to get better. My board initialization takes 19 speeds from 18mhz to 168mhz and uses a lookup table for the MHZ, PLL, APB1, and APB2 values. My code just looks up the values for the speed and sets the registers from that.I spent some time calculating the values and testing them, but now it is easy and certain that I can choose any speed and it will be correct.

author: ppTRN
author_rank: Regular Contributor
timestamp: November 26, 2024, 12:07:44 pm
content: Ok got it. I will modify the registers and then call the function to update it. Is there a prefered order to do so? I mean, should I first call System_Init and then SystemCoreClockUpdate or vice versa?But I guess I'll just try it.Thank you!