Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 239 of 9363. Microcontroller Fundamentals and Bare-Metal CFree lesson

Implementing Phase-Locked Loops for Frequency Multiplication

Configure PLL input dividers, feedback multipliers, and output dividers to synthesize high-speed system clocks from low-frequency crystal or oscillator inputs.

In this lesson, you will learn how to configure a Phase-Locked Loop (PLL) to synthesize a high-frequency system clock from a low-frequency reference oscillator.

Understanding the PLL Concept

Microcontrollers often use low-frequency crystals (e.g., 8 MHz) for stability, but CPUs run much faster. A PLL acts like a digital gear system, multiplying that slow input clock to reach a higher target frequency. It works by creating a feedback loop that adjusts an internal Voltage Controlled Oscillator (VCO) until its output matches the desired multiple of the reference clock.

Configuring the Clock Path

To configure the PLL, you typically interact with three distinct hardware registers or bit-fields:

  1. Input Divider (M): Reduces the raw crystal frequency to a lower "reference" frequency. This ensures the PLL's internal circuitry stays within its stable operating range.
  2. Feedback Multiplier (N): The core multiplier that boosts the divided input frequency.
  3. Output Divider (P): Reduces the high-speed VCO output to the final system clock frequency before it is routed to the CPU and buses.

The math generally follows the formula: F_out = (F_in / M) * N / P.

Practical Implementation

When writing to your hardware registers, always ensure the PLL is disabled before changing these parameters. Changing multipliers while the PLL is actively driving the CPU will cause the system to crash.

// Example: Converting 8MHz crystal to 72MHz System Clock
// 1. Disable PLL
RCC->CR &= ~RCC_CR_PLLON;

// 2. Configure M=2, N=18, P=1 (Example values)
// F_out = (8MHz / 2) * 18 / 1 = 72MHz
RCC->PLLCFGR = (2 << PLL_M_SHIFT) | (18 << PLL_N_SHIFT) | (0 << PLL_P_SHIFT);

// 3. Enable PLL and wait for lock
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));

By adjusting these divisors and multipliers, you precisely tune the internal "heartbeat" of your microcontroller to match the timing requirements of your application.

Key Takeaway: A PLL uses a combination of input division, feedback multiplication, and output division to synthesize a stable high-speed clock from a low-speed reference, provided you update these values only while the PLL is disabled.