Skip to content
Home » Embedded Systems » Why are Crystal Oscillators required?

Why are Crystal Oscillators required?

32.768 KHz quartz crystal oscillator component in a small cylindrical metal package with two wire leads, the standard frequency crystal used in real-time clocks and watch circuits for accurate timekeeping
Embedded Systems Learning Path
Part 9 of 129 — View Full Path →

KEY TAKEAWAYS

  • Crystal oscillators provide stable, accurate clock signals that internal RC oscillators cannot match
  • Crystals vibrate at their natural resonant frequency with very low drift over temperature and time
  • Communication protocols (UART, USB, Ethernet) require precise clocks for reliable data transfer
  • Choose crystal frequency based on your application: 8/16 MHz for processing, 32.768 kHz for timekeeping

Crystal oscillators have only one function. That is to provide stable clock pulses to the digital circuit.

Almost all the digital circuits require clock pulses to operate. A microcontroller requires one too. Clock pulses are required for the synchronization of the operations between various peripherals of the MCU. They also provide the timing for the execution of operations.

A clock pulse(CP) is a string of alternating 0’s and 1’s as in the images below

 
Square wave clock pulse signal oscillating between 0V and 5V showing periodic high and low states with one complete clock pulse cycle marked, representing the output waveform of a crystal oscillator circuit
Diagram showing positive and negative clock pulse waveforms with labeled positive edge and negative edge transitions between logic levels 0 and 1, illustrating how crystal oscillator output defines clock timing

Lets take an example to see the need for CP.

Say your code has only one line to execute

data = 56 – 30;

The following steps are involved in the execution of this line

  1. Load a memory location with the value 56
  2. Load another memory location with the value 30
  3. Perform subtraction
  4. Store the result in the address of “data” variable

(This is only an overview of the execution. A lot more goes on in to execute this line)

The internal circuitry of MCU contains more of like an AND circuit. Its like

“If you have an operation to perform and the clock pulse transits from positive to negative (or negative to positive), execute it”

CP provides the synchronization for the steps involved. The actions can either happen during a positive edge or a negative edge. Lets say it happens at positive pulse (also called rising edge)

  1. CP1 – Load a memory location with the value 56
  2. CP2 – Load another memory location with the value 30
  3. CP3 – Perform subtraction
  4. CP4 – Store the result in the address of “data” variable

This also helps in controlling the speed of execution. A higher frequency clock signal will have more number of pulses per second. Hence, faster execution.

Clock Pulses are also needed to keep track of time. Say you need an LED to glow every 1 second. How is the MCU gonna know that 1 second has elapsed and its time to switch on the LED? The clock pulses come to rescue.

If you have a 1MHz crystal attached, you know there will be 1 x 10^6 pulses. So, you keep counting the pulses and once you get 10^6 pulses, you know 1 second has elapsed. (Again this is only an overview. You will have to configure the registers and interrupts)

Wrist watches and analog clocks also use oscillators. It’s the oscillator that helps them keep track of time precisely. Read more about it here: How does a watch keep working at the same pace until the last drop of a battery cell?

Configuring a Timer Based on Clock Speed

The crystal oscillator frequency directly determines how you configure timers. Here’s how to generate a precise 1-second interrupt on an ATmega328P running at 16 MHz:

/* 1-second timer interrupt using Timer1 (16-bit) on ATmega328P @ 16 MHz */
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t seconds = 0;

ISR(TIMER1_COMPA_vect) {
    seconds++;  /* Increments exactly once per second */
}

void timer1_init(void) {
    /*
     * Clock = 16,000,000 Hz
     * Prescaler = 256 → Timer clock = 62,500 Hz
     * Compare match at 62,499 → interrupt every 62,500 ticks = 1.000 second
     */
    TCCR1B |= (1 << WGM12);              /* CTC mode */
    TCCR1B |= (1 << CS12);               /* Prescaler = 256 */
    OCR1A = 62499;                         /* Compare value for 1 second */
    TIMSK1 |= (1 << OCIE1A);             /* Enable compare match interrupt */
    sei();                                 /* Enable global interrupts */
}

int main(void) {
    timer1_init();
    while (1) {
        /* seconds variable is updated by the ISR exactly once per second */
    }
}

The math: 16,000,000 Hz ÷ 256 (prescaler) = 62,500 ticks/second. Set the compare register to 62,499 (zero-indexed), and the timer fires an interrupt exactly once per second. Change the crystal to 8 MHz, and the compare value must change to 31,249. Get the crystal frequency wrong, and every timer in your system is wrong.

What Happens with the Wrong Oscillator Frequency

If your code assumes 16 MHz but the actual crystal is 8 MHz:

  • UART baud rate is halved — serial communication produces garbage characters
  • Timers run at half speed — a 1-second delay becomes 2 seconds
  • PWM frequencies shift — motors run slower, audio output is wrong
  • I2C/SPI clock is wrong — slave devices may not respond

This is one of the most common debugging headaches for beginners. If your serial output looks like random characters, the first thing to check is whether your code’s assumed clock frequency matches the actual oscillator.

Internal RC vs External Crystal: When to Use Each

  • Internal RC oscillator (±10% accuracy): Use for prototyping, LED blinking, simple GPIO. No extra components needed. Not accurate enough for UART, USB, or precision timing.
  • External ceramic resonator (±0.5%): Good enough for UART at standard baud rates. Cheaper than crystals. Two pins + two load capacitors.
  • External crystal (±0.005%): Required for USB, CAN bus, precise timekeeping, and any application where timing drift is unacceptable. Two pins + two load capacitors (typically 18-22 pF).

Rule of thumb: If your project uses serial communication of any kind, use an external crystal. The internal RC oscillator is too inaccurate for reliable UART.

Leave a Reply

Your email address will not be published. Required fields are marked *