cancel
Showing results for 
Search instead for 
Did you mean: 

about stm32 clock configuration

semed abubakar
Associate II

I am trying to configure my stm32L4 device clock for 80MHz with PLL 

I am trying to understand a piece of code i found online could someone explain what the c code below means

RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLN) | 20U << 8;

RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLM) | 1U << 4; // 000: PLLM = 1, 001: PLLM = 2, 010: PLLM = 3, 011: PLLM = 4, 100: PLLM = 5, 101: PLLM = 6, 110: PLLM 

thank you

5 REPLIES 5

See Reference Manual for bit level definition of register.

Looks to be setting PLLN 20 and PLLM 2, hard to know if that would hit 80 MHz without knowing what the PLL clock source is.

Might help to actually cite the code in question, the selective edit doesn't provide much context.

The code masks out portion of register it wants to change, and then applies the desired value to the right bit position within the register.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
semed abubakar
Associate II

thank you i selected PPL as system clock but i still get only 16MHz on the MCO pin

I am not sure why i checked the registers seems like all that needs to be check is checked

the code is supposed to produce 80MHz

this is the rest the code

void System_Clock_Init(void){

uint32_t HSITrim;

// To correctly read data from FLASH memory, the number of wait states (LATENCY)

 // must be correctly programmed according to the frequency of the CPU clock

 // (HCLK) and the supply voltage of the device.

FLASH->ACR &= ~FLASH_ACR_LATENCY;

FLASH->ACR |= FLASH_ACR_LATENCY_2WS;

// Enable the Internal High Speed oscillator (HSI

RCC->CR |= RCC_CR_HSION;

while((RCC->CR & RCC_CR_HSIRDY) == 0);

// Adjusts the Internal High Speed oscillator (HSI) calibration value

// RC oscillator frequencies are factory calibrated by ST for 1 % accuracy at 25oC

// After reset, the factory calibration value is loaded in HSICAL[7:0] of RCC_ICSCR

HSITrim = 16; // user-programmable trimming value that is added to HSICAL[7:0] in ICSCR.

RCC->ICSCR &= ~RCC_ICSCR_HSITRIM;

RCC->ICSCR |= HSITrim << 24;

RCC->CR  &= ~RCC_CR_PLLON; 

while((RCC->CR & RCC_CR_PLLRDY) == RCC_CR_PLLRDY);

// Select clock source to PLL

RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC;

RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI; // 00 = No clock, 01 = MSI, 10 = HSI, 11 = HSE

// Make PLL as 80 MHz

// f(VCO clock) = f(PLL clock input) * (PLLN / PLLM) = 16MHz * 20/2 = 160 MHz

// f(PLL_R) = f(VCO clock) / PLLR = 160MHz/2 = 80MHz

RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLN) | 20U << 8;

RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLM) | 1U << 4; // 000: PLLM = 1, 001: PLLM = 2, 010: PLLM = 3, 011: PLLM = 4, 100: PLLM = 5, 101: PLLM = 6, 110: PLLM = 7, 111: PLLM = 8

RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLR; // 00: PLLR = 2, 01: PLLR = 4, 10: PLLR = 6, 11: PLLR = 8

RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // Enable Main PLL PLLCLK output 

RCC->CR  |= RCC_CR_PLLON; 

while((RCC->CR & RCC_CR_PLLRDY) == 0);

// Select PLL selected as system clock

RCC->CFGR &= ~RCC_CFGR_SW;

RCC->CFGR |= RCC_CFGR_SW_PLL; // 00: MSI, 01:HSI, 10: HSE, 11: PLL

// Wait until System Clock has been selected

while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);

// The maximum frequency of the AHB, the APB1 and the APB2 domains is 80 MHz.

RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB prescaler = 1; SYSCLK not divided

RCC->CFGR &= ~RCC_CFGR_PPRE1; // APB high-speed prescaler (APB1) = 1, HCLK not divided

RCC->CFGR &= ~RCC_CFGR_PPRE2; // APB high-speed prescaler (APB2) = 1, HCLK not divided

// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;

// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;

// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP; 

// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;

// RCC->PLLCFGR |= RCC_PLLCFGR_PLLPEN; //Enable Main PLL PLLSAI3CLK output enable

// RCC->PLLCFGR |= RCC_PLLCFGR_PLLQEN; //Enable Main PLL PLL48M1CLK output enable

RCC->CR &= ~RCC_CR_PLLSAI1ON; // SAI1 PLL enable

while ( (RCC->CR & RCC_CR_PLLSAI1ON) == RCC_CR_PLLSAI1ON );

// Configure and enable PLLSAI1 clock to generate 11.294MHz 

// 8 MHz * 24 / 17 = 11.294MHz

// f(VCOSAI1 clock) = f(PLL clock input) * (PLLSAI1N / PLLM)

// PLLSAI1CLK: f(PLLSAI1_P) = f(VCOSAI1 clock) / PLLSAI1P

// PLLUSB2CLK: f(PLLSAI1_Q) = f(VCOSAI1 clock) / PLLSAI1Q

// PLLADC1CLK: f(PLLSAI1_R) = f(VCOSAI1 clock) / PLLSAI1R

RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1N;

RCC->PLLSAI1CFGR |= 24U<<8;

// SAI1PLL division factor for PLLSAI1CLK

// 0: PLLSAI1P = 7, 1: PLLSAI1P = 17

RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1P;

RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1PEN;

// SAI1PLL division factor for PLL48M2CLK (48 MHz clock)

// RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1Q;

// RCC->PLLSAI1CFGR |= U1<<21;

// RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1QEN;

// PLLSAI1 division factor for PLLADC1CLK (ADC clock)

// 00: PLLSAI1R = 2, 01: PLLSAI1R = 4, 10: PLLSAI1R = 6, 11: PLLSAI1R = 8

// RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1R; 

// RCC->PLLSAI1CFGR |= U<<25;

// RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1REN;

RCC->CR |= RCC_CR_PLLSAI1ON; // SAI1 PLL enable

while ( (RCC->CR & RCC_CR_PLLSAI1ON) == 0);

// SAI1 clock source selection

// 00: PLLSAI1 "P" clock (PLLSAI1CLK) selected as SAI1 clock

// 01: PLLSAI2 "P" clock (PLLSAI2CLK) selected as SAI1 clock

// 10: PLL "P" clock (PLLSAI3CLK) selected as SAI1 clock

// 11: External input SAI1_EXTCLK selected as SAI1 clock

RCC->CCIPR &= ~RCC_CCIPR_SAI1SEL;

RCC->APB2ENR |= RCC_APB2ENR_SAI1EN;

}

Piranha
Chief II

Maybe MCO outputs HSI? You haven't shown the code that configures MCO output.

P.S. Use "Code Snippet" when posting source code.

semed abubakar
Associate II

thank you

I checked the code and it was HSI on the MCO pin i changed it to system clock

but then the was no signal on the pin

the i tried changing the  MCOPRE[2:0]: Microcontroller clock output prescaler

from 1 to 4 and then there was a signal of 20MHz so i think the system is running at 80MHz cos when i

changed the prescaler to 8 it showed 10MHz on the scope

I am not sure tho why the MCO pin doesnt output the 80MHz i changed the prescaler back to 1 and again there was no signal

is there a speed limit on the MCO pin?

The device should be able to output 80 MHz on MCO, check speed settings on pin configuration, and capabilities of scope and probes.

If the divided down version can be multiplied back to the expected frequency you've proved what the system is working with internally.

You can also print out the value of SystemCoreClock to a terminal/console to see what the processor believes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..