Author Topic: Help me set clock configuration on STM32 - Keil  (Read 919 times)

0 Members and 1 Guest are viewing this topic.

Offline ppTRNTopic starter

  • Regular Contributor
  • *
  • Posts: 133
  • Country: it
Help me set clock configuration on STM32 - Keil
« on: November 25, 2024, 08:09:31 pm »
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: [Select]
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;
      }
#else     
      if (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 source
2. Based on that it writes it into SystemCoreClock (what is that??). The possible sources includes the PLL output

Then 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.

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4341
  • Country: us
Re: Help me set clock configuration on STM32 - Keil
« Reply #1 on: November 26, 2024, 12:44:59 am »
Quote
1. It retrives the system clock source
2. Based on that it writes it into SystemCoreClock
Yes, 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.)
 

Offline rhodges

  • Frequent Contributor
  • **
  • Posts: 349
  • Country: us
  • Available for embedded projects.
    • My public libraries, code samples, and projects for STM8.
Re: Help me set clock configuration on STM32 - Keil
« Reply #2 on: November 26, 2024, 01:02:36 am »
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.
Currently developing embedded RISC-V. Recently STM32 and STM8. All are excellent choices. Past includes 6809, Z80, 8086, PIC, MIPS, PNX1302, and some 8748 and 6805. Check out my public code on github. https://github.com/unfrozen
 

Offline ppTRNTopic starter

  • Regular Contributor
  • *
  • Posts: 133
  • Country: it
Re: Help me set clock configuration on STM32 - Keil
« Reply #3 on: November 26, 2024, 12:07:44 pm »
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!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf