MegaAVR® Oscillator Overview

Last modified by Microchip on 2023/11/14 18:33

Microchip megaAVR® 8-bit microcontrollers have several clock source options, selectable via programming of the CKSEL Flash fuse bits. This discussion is specific to the ATmega328PB MCU.

The fuse bits can select one of:

  • Low-Power Crystal Oscillator
  • Low-Frequency Crystal Oscillator
  • Internal 128 kHz RC Oscillator
  • Calibrated Internal RC Oscillator, and
  • External Clock

The system clock source cannot be changed during run-time, as it is set via fuse programming.

The system clock frequency can be changed during run-time by writing to the System Clock Prescaler register (CLKPR).

Each clock source provides a delay option after the device reset or power-up to keep the device reset until it is supplied with minimum Vcc. The clock from the selected source is input to the AVR® clock generator and routed to the appropriate modules.

megaAVR® maximum operating frequency is dependent on VCC. Application software must ensure that the selected clock source frequency falls within the safe operating area (see section 33.4 in the device data sheet).

Overview

The accompanying image illustrates the principal clock systems in the device and their distribution. All the clocks need not be active at a given time. In order to reduce power consumption, the clocks to modules not being used can be halted by using different sleep modes. The clock systems are described in the following sections. The system clock frequency refers to the frequency generated from the System Clock Prescaler. All clock outputs from the AVR Clock Control Unit run at the same frequency.

AVR Clock Systems Block Diagram
Back to top

Clock Sources

The device has the following clock source options, selectable via CKSEL Flash Fuse bits as shown in the accompanying image. The clock from the selected source is input to the AVR® clock generator and routed to the appropriate modules.

AVR Clock Sourcesx

Default Clock Source

The device is shipped with the internal RC oscillator selected at 8.0 MHz and with the fuse CKDIV8 programmed, resulting in 1.0 MHz system clock. The start-up time is set to maximum, and the time-out period is enabled: CKSEL=0010, SUT=10, CKDIV8=0. This default setting ensures that all users can make their desired clock source setting using any available programming interface.

Clock Startup Sequence

Any clock source needs information a sufficient VCC to start oscillating and (ii) a minimum number of oscillating cycles before it can be considered stable.

Vcc Stability

To ensure sufficient VCC, the device issues an internal reset with a time-out delay (tTOUT) after the device reset is released by all other reset sources:

Vcc Stability

The delay (tTOUT) is timed from the Watchdog Oscillator and the delay time is set by the SUTx and CKSELx fuse bits. The selectable delays for tTOUT are shown in the table below. Note that the frequency of the Watchdog Oscillator is voltage dependent:

Delay Options

VCC is not monitored during the delay, so it is required to select a delay longer than the VCC rise time. If this is not possible, an internal or external Brown-Out Detection (BOD) circuit should be used. A BOD circuit will ensure sufficient VCC before it releases the reset, and the time-out delay can be disabled. Disabling the time-out delay without utilizing a BOD circuit is not recommended.

Oscillator Stability

The oscillator is required to oscillate for a minimum number of cycles before the clock is considered stable. An internal ripple counter monitors the oscillator output clock and keeps the internal reset active for a given number of clock cycles. The reset is then released and the device will start to execute. The recommended oscillator start-up time is dependent on the clock type and varies from 6 cycles for an externally applied clock to 32K cycles for a low-frequency crystal.

Refer to section 11 in the device data sheet which specifies the number of CK delay cycles for each clock source type and SUTx fuse setting.

Back to top

Low Power Crystal Oscillator

Pins XTAL1 and XTAL2 are input and output, respectively, of an inverting amplifier that can be configured for use as an On-chip Oscillator, as shown in the accompanying image. Either a quartz crystal or a ceramic resonator may be used:

Low Power Crystal Oscillator

The Low Power Oscillator can operate in three different modes, each optimized for a specific frequency range. The operating mode is selected by the fuses CKSEL[3:1], as shown in the accompanying image:

Low Power Oscillator Modes

The CKSEL0 Fuse together with the SUT[1:0] Fuses select the start-up times (see section 11.3 in the ATmega328PB datasheet).

Back to top

Low-Frequency Crystal Oscillator

The Low-frequency Crystal Oscillator is optimized for use with a 32.768 kHz watch crystal. The Low-frequency Crystal Oscillator must be selected by setting the CKSEL Fuses to '0110' or '0111', and Start-Up times are determined by the SUT Fuses.

Back to top

Calibrated Internal RC Oscillator

By default, the Internal RC Oscillator provides an 8.0 MHz clock. Though voltage and temperature dependent, this clock can be very accurately calibrated by the user. The device is shipped with the CKDIV8 Fuse programmed, providing a 1 MHz system clock frequency. This clock may be selected as the system clock by programming the CKSEL fuses to '0010':. If selected, it will operate with no external components. During reset, the hardware loads the pre-programmed calibration value into the OSCCAL Register and thereby automatically calibrates the RC Oscillator.

Refer to the AVR053 Application Note which outlines the procedure to re-calibrate the internal RC oscillator.

Back to top

128 kHz Internal Oscillator

The 128 kHz internal oscillator is a low-power oscillator providing a clock of 128 kHz. This clock may be selected as the system clock by programming the CKSEL fuses to '0011'.

Back to top

External Clock

To drive the device from an external clock source, EXTCLK should be driven as shown in the accompanying image. To run the device on an external clock, the CKSEL Fuses must be programmed to '0000'.

External Clock Drive Configuration

Back to top

Clock Output Buffer

The device can output the system clock on the CLKO pin. To enable the output, the CKOUT Fuse has to be programmed. This mode is suitable when the chip clock is used to drive other circuits on the system. The clock also will be output during reset, and the normal operation of I/O pin will be overridden when the fuse is programmed. Any clock source, including the internal RC Oscillator, can be selected when the clock is output on CLKO. If the System Clock Prescaler is used, it is the divided system clock that is output.

Back to top

Timer/Counter Oscillator

The device uses the same crystal oscillator for Low-frequency Oscillator and Timer/Counter Oscillator. See Low-Frequency Crystal Oscillator for details on the oscillator and crystal requirements.

On this device, the Timer/Counter Oscillator Pins (TOSC1 and TOSC2) are shared with EXTCLK. When using the Timer/Counter Oscillator, the system clock needs to be four times the oscillator frequency. Due to this and the pin sharing, the Timer/Counter Oscillator can only be used when the Calibrated Internal RC Oscillator is selected as the system clock source. Applying an external clock source to TOSC1 can be done if the Enable External Clock Input bit in the Asynchronous Status Register (ASSR.EXCLK) is written to '1'. See the description of the Asynchronous Operation of Timer/Counter2 for further description on selecting an external clock as the input instead of a 32.768 kHz watch crystal.

Back to top

System Clock Prescaler

The device has a system clock prescaler, and the system clock can be divided by configuring the Clock Prescale Register (CLKPR). This feature can be used to decrease the system clock frequency and power consumption when the requirement for processing power is low. This can be used with all clock source options, and it will affect the clock frequency of the CPU and all synchronous peripherals. clkI/O,clkADC, clkCPU, and clkFLASH are divided by a factor as shown in the CLKPR description:

External Clock Prescaler

CLKPR

Back to top

Writing to CLKPR

When switching between prescaler settings, the System Clock Prescaler ensures that no glitches occur in the clock system. It also ensures that no intermediate frequency is higher than either the clock frequency corresponding to the previous setting or the clock frequency corresponding to the new setting. The ripple counter that implements the prescaler runs at the frequency of the undivided clock, which may be faster than the CPU's clock frequency. Hence, it is not possible to determine the state of the prescaler - even if it were readable, the exact time it takes to switch from one clock division to the other cannot be exactly predicted. From the time the Clock Prescaler Selection bits (CLKPS[3:0]) values are written, it takes between T1 + T2 and T1 + 2 * T2 before the new clock frequency is active. In this interval, two active clock edges are produced. Here, T1 is the previous clock period, and T2 is the period corresponding to the new prescaler setting. To avoid unintentional changes of clock frequency, a special write procedure must be followed to change the CLKPS bits:

  1. Write the Clock Prescaler Change Enable (CLKPCE) bit to '1' and all other bits in CLKPR to zero: CLKPR=0x80.
  2. Within four cycles, write the desired value to CLKPS[3:0] while writing a zero to CLKPCE: CLKPR=0x0N

Interrupts must be disabled when changing prescaler setting to make sure the write procedure is not interrupted.

Code Sample

The following function can be used to dynamically update CLKPR as required above. Note the usage of cli() and sei() functions to ensure that the CLKPR write procedure is uninterrupted.

#include <stdint.h>  // Std integral type definitions
#include
<avr/io.h>  // SFR definitions
#include
<avr/interrupt.h> // ISR macros

void clkPrescaleSet(uint8_t divisionFactor){
    cli();                        // disable interrupts
   CLKPR = (1 << CLKPCE);        // enable change of the CLKPSx bits
   CLKPR = divisionFactor;       // update the CLKPSx bits
   sei();                        // re-enable interrupts
}

To see this function in use, please visit the megaAVR® Oscillator Example Project.

Back to top

CLKDIV8 Fuse & CLKPR

The CKDIV8 Fuse determines the initial value of the CLKPS bits. If CKDIV8 is unprogrammed, the CLKPS bits will be reset to “0000”. If CKDIV8 is programmed, CLKPS bits are reset to “0011”, giving a division factor of 8 at start-up. This feature should be used if the selected clock source has a higher frequency than the maximum frequency of the device at the present operating conditions. Note that any value can be written to the CLKPS bits regardless of the CKDIV8 Fuse setting. The Application software must ensure that a sufficient division factor is chosen if the selected clock source has a higher frequency than the maximum frequency of the device at the present operating conditions. The device is shipped with the CKDIV8 Fuse programmed.

Back to top

Learn More

megaAVR® Oscillator Example Project

Back to top