Clock Options

The clock unit of the AVR timers consists of a prescaler connected to a multiplexer. A prescaler can be considered as a clock divider. Generally, it is implemented as a counter with several output signals at different counting stages. In the case of the ATmega328PB, a 10-bit counter is used to divide the input clock in four (six in case of the Timer2) different prescaled clocks. The multiplexer is used to select which prescaled clock signal to use as input signal for the Timer. Alternatively, the multiplexer can be used to bypass the prescaler and configure an external pin to be used as input for the Timer.

There are two prescaler blocks available in the device. Since Timer0 and Timer1 are synchronous timers and use the system clock (CPU clock) as input source, they can use the same prescaler block (as long as each timer can be configured separately using the corresponding CSxx bits). However, the asynchronous clocked Timer2 needs its own prescaler to be independent of the system clock.

The following figure shows the prescaling and the configuration unit for Timer0/1. The data sheets contain more detailed drawings showing all prescalers and multiplexers. An overview of the possible clock settings is given in Table 1. In the following sections these settings will be described more clearly.

Note:
  1. The prescaler is constantly running during operation. In cases where the timer has to count very accurately it has to be ensured that the prescaler starts counting from zero.
  2. On devices with shared prescaler, executing a prescaler reset will affect all connected timers.
Figure 1. Prescaler for Timer0/1

Clocking by System Clock

In this case, the system clock is used as input signal for the prescaler. Even if a prescaled value is chosen instead of the system clock, this clock is based on the system clock. The timer clock is therefore synchronous to the system clock. All five timers of the ATmega328PB and most timers on other AVR parts support this option. Small time frames can be implemented or monitored because of the high frequency of the system clock. The timer overflow frequency is a good indication of the size of the time frame a timer covers. Equation 1 shows the correlation between the timer overflow frequency TOVCK, the maximum value (MaxVal) of the timer, the system clock (CK), and the division factor of the prescaler (PVal).

Table 1. Overview of the Clock Settings
TCCRx Synchronous Timer0 and Timer1 PCK = CK Synchronous/Asynchronous Timer2 PCK2 = f (AS2)
Bit 2 Bit 1 Bit 0
CSx2 CSx1 CSx0 TCK0/1 TCK2
0 0 0 0 (Timer Stopped) 0 (Timer Stopped)
0 0 1 PCK (System Clock) PCK2 (System Clock/Asynchronous Clock)
0 1 0 PCK/8 PCK2/8
0 1 1 PCK/64 PCK2/32
1 0 0 PCK/256 PCK2/64
1 0 1 PCK/1024 PCK2/128
1 1 0 External Clock on Tn pin PCK2/256
1 1 1 External Clock on Tn pin PCK2/1024

Assume that the CPU is running with f CPU = 1MHz and the resolution of the timer is 8 bit (MaxVal = 256). A prescale value of 64 will then cause the timer to be clocked with TCK = 1MHz/64 so that there will be about 61 timer overflows per second. See Equation 2 for the correct mathematical description:

To get 61 timer overflow events per second means that every 16ms an overflow occurs. The maximum prescaler value will generate a timer overflow every ~262ms while the minimum prescaler value generates a timer overflow every 256µs.

In most cases a different approach will be used to determine the settings. The requirements of the application will specify the frequency of the timer overflows. Based on this and the given clock frequency of the CPU together with the timer resolution the prescaler settings will be calculated according to the following equation.
The assembler implementation for Timer0 can look like the following code example. These lines set the prescaler values in the TCCR0B to a clock division factor of 1024.
ldi	r16,(1<<CS02)|(1<<CS00)
sts	TCCR0B,r16	; Timer clock = system clock/1024

Clocking by Asynchronous Clock

In contrast to the two other timers, which do not support this option, Timer2 of the ATmega328PB can be clocked by an asynchronous external clock. For this purpose a crystal or a ceramic resonator can be connected to the on-board oscillator via the pins TOSC1 and TOSC2. The oscillator is optimized for a watch crystal of 32.768kHz. This frequency is well suited for the implementation of Real Time Clocks (RTC). For more information, See AVR134: Real Time Clock (RTC) using the Asynchronous Timer. The main advantage of a separate clock is that it is independent of the system clock. This makes it possible to run the part at a high processing frequency while the timer is clocked by an external clock with a frequency optimized for accurate timing. Additional power save mode support allows putting the part in sleep mode while the asynchronous timer is still in duty.

Asynchronous operation requires some additional consideration. Because the clocking of Timer2 is asynchronous, the timer events have to be synchronized by the CPU. This requires a timer clock frequency, which is at least four times lower than the system clock. On the other hand, conflicts between the synchronous and the asynchronous access have to be avoided. This is done by using temporary registers. Status bits signalize when an update of the configuration registers is in process. See the description of the Asynchronous Status Register (ASSR) in the data sheet for details.

The TOVCK is calculated according to Equation 2, but by using the oscillator frequency instead of the system clock. The settings of TCCR2B are given in Table 1. The prescaler input clock PCK2 is a function of the AS2 bit in the ASSR register. If this bit is cleared, the timer runs in synchronous mode with the system clock as input frequency. If this bit is set, the asynchronous clock signal on the pins TOSC1 and TOSC2 is used as input signal of the prescaler.

The assembler implementation for Timer2 can look like the following code example. These two lines set the prescaler values in TCCR2B to a clock division factor of 1024 (see Table 1).
ldi	r16, (1<<CS22)|(1<<CS21)|(1<<CS20)
sts	TCCR2B,r16	; Timer clock = system clock/1024

External Clocking

External clocking is supported by Timer0 and Timer1 only. This mode allows the use of a wide range of external signals as timer clock signals. This is synchronous clocking, which means that the CPU detects the status of the pin and clocks the timer synchronously to the system clock if an external clock signal was detected. The T1/T0 pin is sampled once every system clock cycle by the pin synchronization logic. The synchronized (sampled) signal is then passed through an edge detector. This clocking option is selected in TCCRx, the settings of the bits CS00, CS01, and CS02 can be found in Table 1.

The assembler implementation for the Timer0 can look like the following code example. These lines set pin T0 as input pin for the timer clock with the rising edge as the active clock edge.
ldi	r16,(1<<CS02)|(1<<CS01)|(1<<CS00)
sts	TCCR0B,r16	; Timer clock = external pin T0, rising edge
Note: It is important to ensure that pin T0 is an input pin in the Data Direction Register of Port B (DDRB). The setting of the direction register will not be overwritten by the timer setup, because it is also allowed to implement a software clocked timer in the AVR. T0 and T1 are inputs by default.

How to Stop the Timer

Stopping the timer from counting is simple. A value of zero as prescaler values in the TCCRx stops the corresponding timer (see Table 1). However, remember that the prescaler is still running.

The assembler implementation for the Timer0 can look like the following code example.
clr		r16	
sts		TCCR0B,r16	; writing zero to TCCR0B stops Timer 0
Note: Other TCCRx may contain configuration bits beside the clock select (CSxx) bits. The command lines above will clear these bits. This has to be avoided if these bits were set. That costs one extra line of code, as shown in the following code snippet.
lds		r16,TCCR0B	; Load current value of TCCR0B
andi	r16,~((1<<CS02)|(1<<CS01)|(1<<CS00))
					; Clear CS02,CS01,CS00
sts		TCCR0B,r16	; Writing zero to CS02, CS01, and CS00 in TCCR0B stops Timer0. The other bits are not affected