MegaAVR® Oscillator Overview
Contents
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
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.
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.
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.
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 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:
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:
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.
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:
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:
The CKSEL0 Fuse together with the SUT[1:0] Fuses select the start-up times (see section 11.3 in the ATmega328PB datasheet).
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.
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.
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'.
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'.
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.
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.
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:
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:
- Write the Clock Prescaler Change Enable (CLKPCE) bit to '1' and all other bits in CLKPR to zero: CLKPR=0x80.
- Within four cycles, write the desired value to CLKPS[3:0] while writing a zero to CLKPCE: CLKPR=0x0N
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 <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
}
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.