blabla

We will use STM32F103 series for these examples. First, before we do anything, we must set up the chip clock. That means to determine frequency at which the chip will work, select clock source, enable/disable real time clock if we need it etc... First we will download the reference manual for STM32F103C8T6 from ST page and open it on chapter 7, Low, medium, high and XL density reset and clock control (RCC). RCC is short name for that register group.

...

From this schematics we can see exactly what we need to do. If we look at the symbol named SW, we can choose between 3 clock sources:
external oscillator, PLL and internal 8MHz oscillator.
We will use PLL with external oscillator so we need to set PLLCLK for SW and choose PLLSRC as HSE OSC. PLLMUL is PLL multiplier, we will set it to 9.
According to schematics, maximum clock speed for APB1 is 36MHz, so we will need to use APB1 prescaler of 2 to lower the clock speed from 72MHz down to 36MHz. AHB prescaler can stay 1.
Starting point of our coding is manufacturer's website. https://www.st.com/en/microcontrollers-microprocessors/stm32f103c8.html
Download datasheet and reference manual. We start on page 90 of reference manual: Low-, medium-, high- and XL-density reset and clock control (RCC)

						
						RCC->CR|=RCC_CR_HSEON_Msk;
						while(!(RCC->CR & RCC_CR_HSERDY))
						RCC->CFGR&=~0xFFFF;
						RCC->CFGR|=0b0111<< RCC_CFGR_PLLMULL_Pos;
						CFGR|=RCC_CFGR_PLLSRC_Msk;
						RCC->CR|=RCC_CR_PLLON_Msk;
						
						
1) Enable HSE

Enable HSE - High speed external oscillator by writing 1 into Clock control register (RCC_CR) bit HSE ON

						
						RCC->CR |=RCC_CR_HSEON;
						
						

And now we wait until HSE Ready flag has been set

						
						while(!(RCC->CR & RCC_CR_HSERDY))
						
						
2) Set PLLXTPRE.

A simple while loop will do it for us. We wait while RCC_CR_HSERDY has been set in RCC_CR register Search the registers and you'll find it in RCC_CFGR register where the datasheet says
Bit 17
PLLXTPRE: HSE divider for PLL entry
Set and cleared by software to divide HSE before PLL entry. This bit can be written only when PLL is disabled.
0: HSE clock not divided
1: HSE clock divided by 2
we will choose not to divide HSE clock, doesn't matter really since we can adjust the PLL multiplier. So we leave this one alone or set it to 0 to be sure it's zero.

						
						RCC->CFGR &=~RCC_CFGR_PLLXTPRE;
						
						
3) Setting PLL Source:


RCC_CFGR register, bit 16
Bit 16
PLLSRC: PLL entry clock source
Set and cleared by software to select PLL clock source. This bit can be written only when PLL is disabled.
0: HSI oscillator clock / 2 selected as PLL input clock
1: HSE oscillator clock selected as PLL input clock
We want to use HSE oscillator as PLL input clock so we set it to 1:

						
						RCC->CFGR |=RCC_CFGR_PLLSRC;
						
						
4) Setting PLL multiplier:

RCC_CFGR register, bits 18-21
To get main clock of 72MHz we will choose multiplier 9 and from datasheet we find out what value we must write into a register 0111: PLL input clock x 9
We need to write 0b0111 shifted by 18 bits

						
						RCC->CFGR |=0b0111<< RCC_CFGR_PLLMUL_Pos;
						
						

RCC_CFGR_PLLMUL_Pos is just a name (define) for number 18 - position of PLLMUL bits

Copyright 2024, Mario Matovina
Send me an e-mail