3 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 3-1. In the following sections these settings will be described more clearly.
- 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.
- On devices with shared prescaler, executing a prescaler reset will affect all connected timers.
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).
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.
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 3-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.
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 3-1.
ldi r16,(1<<CS02)|(1<<CS01)|(1<<CS00)
sts TCCR0B,r16 ; Timer clock = external pin T0, rising edge
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 3-1). However, remember that the prescaler is still running.
clr r16
sts TCCR0B,r16 ; writing zero to TCCR0B stops Timer 0
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