Oscillator and Types of Oscillator, Clock Cycle, Over Clocking and Under Clocking in Embedded Systems

Oscillator and types of oscillator, Clock Cycle, Over Clocking and Under Clocking

When I first started working with microcontrollers, I honestly underestimated the oscillator. I thought of it as a background component — something that “just makes the chip tick.” It didn’t take long before I ran into a project where a wrong crystal load capacitor value caused my UART to spit out garbage characters, and that’s when I really learned how central the oscillator is to everything an embedded system does. In this article, I’m going to walk through what an oscillator is, the different types you’ll encounter, how clock cycles actually drive instruction execution, and what happens — good and bad — when you overclock or underclock a microcontroller.

What Is an Oscillator in an Embedded System?

An oscillator is a circuit that produces a periodic, repetitive electronic signal, usually a square wave or sine wave, at a specific frequency. This signal is the heartbeat of a digital system. Every microcontroller, microprocessor, and digital IC needs a clock signal to synchronize its internal operations — fetching instructions, executing them, moving data between registers, and talking to peripherals.

Without a stable clock, a CPU has no way of knowing when one operation ends and the next begins. Digital logic in a synchronous system is built around flip-flops and registers that only change state on a clock edge (rising edge, falling edge, or both). The oscillator is what generates that edge, over and over, millions or billions of times per second.

flowchart LR
    A[Oscillator Circuit] -->|Clock Signal CLK| B[PLL / Clock Divider]
    B --> C[CPU Core]
    B --> D[Peripheral Bus - APB/AHB]
    D --> E[Timers]
    D --> F[UART/SPI/I2C]
    D --> G[ADC/DAC]
    B --> H[Flash/Memory Controller]

Why the Oscillator Matters So Much

I like to explain it this way: if the CPU is a factory worker, the clock is the conveyor belt. The worker can only pick up the next part when the belt moves. If the belt moves too slowly, production is slow. If it moves too fast for the worker to keep up, parts get dropped or mishandled. That’s essentially what happens inside silicon — logic gates need a certain amount of time (propagation delay) to settle after each clock edge, and the clock frequency must respect that physical limit.

Types of Oscillators Used in Embedded Systems

There are several oscillator types, each with different trade-offs in accuracy, cost, power consumption, and start-up time.

1. Crystal Oscillator (XTAL)

This is the most common oscillator type in embedded systems. It uses a quartz crystal that vibrates at a very precise mechanical resonant frequency when an electric field is applied (piezoelectric effect). Crystal oscillators are prized for their excellent frequency stability, often within ±20 to ±100 parts per million (ppm).

A typical crystal oscillator circuit (Pierce oscillator) connects the crystal between two pins of the microcontroller (XTAL1/XTAL2 or OSC_IN/OSC_OUT), along with two small load capacitors to ground.

flowchart TB
    MCU[Microcontroller] -->|XTAL1| X1((Crystal))
    MCU -->|XTAL2| X1
    X1 --> C1[Load Cap C1]
    X1 --> C2[Load Cap C2]
    C1 --> GND1[GND]
    C2 --> GND2[GND]

I’ve personally had boards fail to oscillate simply because the load capacitor values didn’t match the crystal’s datasheet specification. This is a very common rookie mistake — always check the crystal’s load capacitance (CL) rating and calculate C1/C2 using the formula:

CL = (C1 * C2) / (C1 + C2) + Cstray

2. Ceramic Resonator

A cheaper alternative to quartz crystals, ceramic resonators offer decent accuracy (around ±0.5%) but are less stable over temperature variation. They’re common in cost-sensitive consumer products like toys, remote controls, and low-end peripherals where extreme timing precision isn’t required.

3. RC Oscillator (Internal/External)

RC oscillators use a resistor-capacitor network to generate a clock frequency. Most microcontrollers, including STM32, AVR, and PIC devices, have an internal RC oscillator (like STM32’s HSI — High Speed Internal). These are convenient because they require zero external components, but accuracy is poor (±1% to ±5%) and drifts significantly with temperature and voltage.

I usually use the internal RC oscillator during early prototyping when I just want the board to boot up and blink an LED, then switch to an external crystal once timing-critical peripherals like UART or USB come into play.

4. Crystal Oscillator Module (Active Oscillator/XO)

This is a fully self-contained oscillator module with the crystal, driving circuit, and output buffer all packaged together. It outputs a clean square wave directly and doesn’t need external load capacitors. These are used when board space or circuit complexity needs to be minimized, or in high-frequency systems (like FPGA reference clocks).

5. Temperature-Compensated Crystal Oscillator (TCXO)

A TCXO includes internal circuitry that compensates for frequency drift caused by temperature changes, achieving stability in the range of ±0.5 to ±2 ppm. These are used in GPS modules, cellular modems, and other applications where timing precision directly affects functional accuracy.

6. Voltage-Controlled Oscillator (VCXO) and Oven-Controlled Oscillator (OCXO)

VCXOs allow frequency to be fine-tuned by an input voltage — useful in phase-locked loop (PLL) circuits. OCXOs place the crystal inside a temperature-controlled “oven” to hold an almost constant temperature, giving extremely high stability (used in telecom base stations, lab equipment, and precision timing systems). I haven’t personally needed OCXO-level precision in typical embedded projects, but it’s worth knowing they exist for reference-grade timing applications.

Comparison Table

Oscillator TypeAccuracyCostStartup TimeTypical Use
Internal RC±1–5%Free (built-in)Fast (µs)Prototyping, non-critical timing
Ceramic Resonator±0.5%LowFastConsumer electronics
Crystal (XTAL)±20–100 ppmMediumSlower (ms)UART, USB, precision timing
TCXO±0.5–2 ppmHighMediumGPS, cellular modules
OCXO<±0.01 ppmVery HighLong (warm-up)Telecom, lab instruments

Clock Cycle: The Fundamental Unit of Time in a Processor

A clock cycle (or clock tick) is one complete period of the oscillator’s waveform — the time it takes to go from one rising edge to the next rising edge. If a microcontroller runs at 16 MHz, each clock cycle takes:

T = 1 / f = 1 / 16,000,000 = 62.5 nanoseconds

Every instruction a CPU executes takes a certain number of clock cycles. Simple instructions like a register move might take one cycle; more complex operations like multiplication or memory access might take several. This is why datasheets list “instructions per cycle” (IPC) or “cycles per instruction” (CPI) as key performance metrics.

sequenceDiagram
    participant CLK as Clock Signal
    participant CPU as CPU Core
    CLK->>CPU: Rising Edge 1 - Fetch Instruction
    CLK->>CPU: Rising Edge 2 - Decode Instruction
    CLK->>CPU: Rising Edge 3 - Execute Instruction
    CLK->>CPU: Rising Edge 4 - Write Back Result

The Fetch-Decode-Execute Cycle

Internally, the CPU’s instruction cycle is broken into stages, and each stage is timed by the clock:

  1. Fetch — the CPU reads the next instruction from flash/program memory using the Program Counter (PC).
  2. Decode — the instruction decoder figures out what operation is being requested.
  3. Execute — the ALU (Arithmetic Logic Unit) or relevant peripheral performs the operation.
  4. Write-back — results are stored back into registers or memory.

On simple 8-bit microcontrollers like the AVR (ATmega328P used in Arduino Uno), most single-cycle instructions complete in one clock cycle at 16 MHz, giving roughly 16 million instructions per second under ideal conditions. On more advanced ARM Cortex-M cores, pipelining lets multiple stages overlap, effectively increasing throughput without raising the clock frequency.

Example: Timer Calculation Based on Clock Cycle

Here’s a practical C example showing how the clock cycle affects timer configuration on an AVR microcontroller:

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL   // 16 MHz clock

void timer1_init(void) {
    // Configure Timer1 for CTC mode
    TCCR1B |= (1 << WGM12);       
    // Set prescaler to 1024
    TCCR1B |= (1 << CS12) | (1 << CS10);
    
    // Calculate compare value for 1 second interrupt
    // OCR1A = (F_CPU / (prescaler * desired_freq)) - 1
    OCR1A = (F_CPU / (1024UL * 1)) - 1;  // = 15624
    
    TIMSK1 |= (1 << OCIE1A);      // Enable Timer1 compare interrupt
    sei();                        // Enable global interrupts
}

ISR(TIMER1_COMPA_vect) {
    // Executes once every second
    PORTB ^= (1 << PB5);  // Toggle onboard LED
}

int main(void) {
    DDRB |= (1 << PB5);  // Set LED pin as output
    timer1_init();
    while (1) {
        // Main loop does other work
    }
}

This shows directly how the system clock frequency (F_CPU) feeds into every timing calculation in firmware. Get the oscillator wrong, and every derived timing value — baud rates, PWM frequency, timer intervals — is wrong too.

Overclocking in Embedded Systems

Overclocking means running the CPU or peripheral clock above its rated/specified frequency, hoping to extract more performance. In the PC world, overclocking is a hobbyist sport. In embedded systems, it’s riskier because these devices often run unattended, in harsh environments, and for years without a reboot.

How Overclocking Works

Microcontrollers usually derive their core clock from an internal or external oscillator through a PLL (Phase-Locked Loop), which multiplies the reference frequency. For example, an STM32F103 might use an 8 MHz external crystal, multiplied by a PLL factor of 9 to reach 72 MHz. Overclocking involves pushing that PLL multiplier beyond the manufacturer’s specified maximum.

flowchart LR
    OSC[8 MHz Crystal] --> PLL[PLL x9]
    PLL --> SYSCLK[SYSCLK = 72 MHz Rated]
    PLL -.->|Overclocked x12| OC[SYSCLK = 96 MHz Unrated]

Risks of Overclocking

  • Timing violations: Flash memory read access time may not keep up with a faster core clock, causing instruction fetch errors or random crashes.
  • Increased power consumption and heat: Dynamic power scales roughly with frequency and the square of voltage (P ∝ C·V²·f), so pushing frequency higher without adequate cooling can cause thermal issues.
  • Reduced long-term reliability: Running silicon outside its characterized operating range accelerates electromigration and can shorten device lifespan.
  • Peripheral desync: Communication peripherals like UART, SPI, and I2C depend on precise clock division; overclocking the core without adjusting peripheral dividers can break communication timing entirely.
  • Voided warranty/certification: For commercial products, running outside datasheet specs can void regulatory certifications (EMC/EMI compliance is tested at rated clock speeds).

I would only ever consider overclocking in a personal hobby project — never in a product that ships to customers, where I need guaranteed, repeatable behavior across temperature and voltage variation.

Practical Overclocking Example (STM32 Register-Level Concept)

// Conceptual example: pushing PLL multiplier beyond spec (NOT recommended for production)
RCC->CFGR &= ~RCC_CFGR_PLLMULL;
RCC->CFGR |= RCC_CFGR_PLLMULL12;   // Overclocked multiplier (unrated)
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));  // Wait for PLL lock
RCC->CFGR |= RCC_CFGR_SW_PLL;        // Switch system clock to PLL

Underclocking in Embedded Systems

Underclocking is the opposite: deliberately running the processor below its maximum rated frequency. Unlike overclocking, underclocking is a completely standard and widely used technique in professional embedded and IoT design — especially for battery-powered devices.

Why Underclocking Is Useful

  • Power savings: Dynamic power draw is roughly proportional to clock frequency, so halving the clock frequency can meaningfully reduce current draw, extending battery life for sensor nodes, wearables, and remote IoT devices.
  • Reduced EMI: Lower clock speeds generate less electromagnetic interference, useful in noise-sensitive analog systems (like precision ADC readings).
  • Thermal management: In enclosed, fanless designs, underclocking keeps junction temperature within safe limits.
  • Sufficient performance for the task: If your application just needs to read a sensor every 10 seconds and go back to sleep, running at full speed is wasted energy.

Dynamic Clock Scaling Example

Many modern MCUs support dynamic frequency scaling, changing clock speed at runtime based on workload. Here’s a conceptual example on an STM32 using HAL:

void switch_to_low_power_clock(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    // Use internal HSI oscillator at reduced frequency, no PLL
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}

This kind of clock switching, combined with sleep modes (Stop, Standby), is a core technique in low-power IoT firmware design.

Real-World Application: Balancing Clock Speed in an IoT Sensor Node

Imagine designing a battery-powered soil moisture sensor that wakes up every 15 minutes, takes a reading, transmits it over LoRa, and sleeps again. Running the MCU at full 168 MHz the entire time would drain the battery in days. Instead, a practical firmware design:

  1. Wakes from Standby mode using an RTC (real-time clock) driven by a separate low-power 32.768 kHz crystal.
  2. Switches to a modest clock speed (e.g., 8 MHz) just fast enough to read the ADC and format a data packet.
  3. Enables the higher-speed PLL clock only briefly if fast SPI/LoRa transmission demands it.
  4. Returns to Standby, cutting power consumption to microamps.

This layered clocking strategy — separate low-power oscillator for timekeeping and a scalable main oscillator for processing — is standard practice across nearly all commercial IoT products.

Performance, Reliability, and Security Considerations

  • Performance: Clock speed directly determines throughput, but real-world performance also depends on memory wait states, bus architecture, and pipeline efficiency — simply raising frequency doesn’t always yield proportional gains.
  • Reliability: Oscillator stability affects communication protocol reliability. A drifting clock on one UART node relative to another can cause bit errors as baud rate mismatches accumulate over a frame.
  • Security: Clock glitching is an actual hardware attack technique, where an attacker deliberately injects glitches into the clock line to cause a processor to skip an instruction (for example, bypassing a security check). This is why some secure microcontrollers include internal clock monitoring circuits that detect abnormal clock behavior and trigger a reset or lockout.

Frequently Asked Questions

Q: Can I run any microcontroller without an external crystal? Yes, most modern MCUs have an internal RC oscillator that can run the chip standalone. However, for USB communication, precise UART baud rates, or RTC timekeeping, an external crystal is usually necessary.

Q: Why does my UART output garbage characters after changing the clock source? This almost always means the baud rate generator’s assumed clock frequency doesn’t match the actual running clock. Recalculate your baud rate registers whenever you change F_CPU or the system clock source.

Q: Is overclocking a microcontroller ever acceptable in a commercial product? Generally no. Commercial products need guaranteed behavior over their full rated temperature and voltage range, and running outside datasheet specifications risks certification and reliability issues.

Q: What’s the difference between system clock and peripheral clock? The system clock (SYSCLK) drives the CPU core, while peripheral clocks (like APB1, APB2 on STM32) are often derived from SYSCLK through dividers, allowing different peripherals to run at different, appropriate speeds.

Q: Why do real-time clocks (RTC) use a separate 32.768 kHz crystal? 32.768 kHz = 2^15, which makes it trivial to divide down to a clean 1 Hz signal for timekeeping using simple binary counters, and it consumes very little power compared to a high-frequency main oscillator.

Summary

The oscillator is far more than a supporting component — it is the timing backbone of every embedded system. Choosing the right oscillator type (internal RC, ceramic resonator, crystal, or TCXO) depends on the accuracy, cost, and power trade-offs your project demands. Clock cycles define how fast instructions execute and how peripherals are timed, which is why every timer, UART baud rate, and PWM frequency calculation traces back to the system clock. Overclocking may sound tempting for extra performance but introduces real reliability and certification risks, while underclocking is a proven, mainstream strategy for extending battery life in IoT and portable embedded devices. Understanding how to select, configure, and manage your oscillator and clock system is one of the most foundational skills in embedded development.

References

Total
2
Shares

Leave a Reply

Previous Post
What is the concept of a state-value function in reinforcement learning?

What Is the Concept of a State-Value Function in Reinforcement Learning?

Next Post
Introduction to Computer Network, OSI MODEL and Need of OSI model

Introduction to Computer Networks, OSI Model, and the Need for the OSI Model

Related Posts