Arduino UNO – Timers

The Arduino Uno board is based on the ATmega328P microcontroller, which has three timers available for various timing and PWM operations. To follow along with this article, I recommend opening the datasheet on the indicated pages when prompted.

Right away on page 1, we can find that the ATmega328P has the following peripherals features related with timers:

The block diagram on page 6, gives the first hint on which timer is 8 or 16 bits.

  • T/C 0 (Timer 0): 8-bit
  • T/C 1 (Timer 1): 16-bit
  • T/C 2 (Timer 2): 8-bit

Hardware timers for a microcontroller, are typically built with counters [REF 1], increment logic, compare registers, control logic, and a clock source. The clock source is important to drive the internal logic (e.g.: flip flops).

The block diagram above, doesn’t include that clock information, mainly because it would be confusing to have all that information concentrated in one diagram.

If you scroll down the datasheet to page 24, “System clock and Clock Options“, you will find a clock distribution block diagram.

We can see that the timer/counter module is driven by the clk_I/O and clk_ASY, that comes from the AVR Clock Control Unit.

The Arduino UNO board has a 16MHz crystal oscillator that supplies the source clock to the AVR Clock Control Unit. You can find that information on the reference schematic design, where you can see a 16MHz ceramic resonator connected to the XTAL2 and XTAL1 from the MCU.

Between the AVR Control Unit and the Crystal Oscillator modules, there is a Clock Multiplexer and a System Clock Prescaler.

Note: up to this point, I still don’t know where this Clock Multiplexer and System Clock Prescaler are being initialized or defined. All I know is when we set up the Board to “Arduino Uno” (image below), the AVR Clock Control Unit is providing a clk_CPU and clk_I/O of 16MHz. This section will be updated accordingly as soon as I find out where that information is.

You can add a couple of lines of code that reads the “F_CPU” macro to confirm the clk_CPU value of your Arduino UNO board.

void setup() 
{
  Serial.begin(9600);

  uint32_t cpuFrequency = F_CPU;
  Serial.println(cpuFrequency);
}

void loop() {
}

For Timer 0 and Timer 1, on page 114, mentions that it is possible to run the Timer/Counter clock frequency equal to the system clock frequency. That means clk_IO = clk_CPU.

On page 115, we can see that it is possible to set the multiplexer to route clk_IO directly to clk_T1 and clk_T0.

On page 87 you can find the clock select bit table for Timer 0.

On page 110 you can find the clock select bit table for Timer 1.

For Timer 2, the clock source clk_T2 is by default equal to the MCU clock, clk_IO.

On page 127, we can see that it is possible to set the multiplexer to route clk_IO directly to clk_T2.

On page 131 you can find the clock select bit table for Timer 2.

Any of the timers can be configured for different modes, such as Normal mode, CTC (Clear Timer on Compare Match) mode, Fast PWM mode, and Phase Correct PWM mode, depending on your specific requirements.

Timer/Counter0 is an 8-bit timer that is commonly used for generating PWM signals on pins 5 and 6 (OC0B and OC0A). It is also used by the millis() and micros() functions for timing operations.

Note: It is important to pay attention when to use Timer 0 properly. If in your code you are using any of the delay functions, Timer 0 becomes a critical peripheral to use because it is already being used by those functions.

To select the mode, on page 86 you can find the waveform generation mode bit table for Timer 0.

And around this table you can find the registers that we need to change in order to select the desired functionality.

Timer/Counter1 is a 16-bit timer that provides more features and flexibility compared to Timer/Counter0. It is commonly used for generating PWM signals on pins 9 and 10 (OC1A and OC1B), as well as for various timing operations.

On page 109 you can find the waveform generation mode bit table for Timer 1.

And around this table you can find the registers that we need to change in order to select the desired functionality.

Timer/Counter2 is another 8-bit timer similar to Timer/Counter0. It is commonly used for generating PWM signals on pins 3 and 11 (OC2A and OC2B).

On page 130 you can find the waveform generation mode bit table for Timer 2.

And around this table you can find the registers that we need to change in order to select the desired functionality.

We are now in good shape to see an example, and hopefully we can understand how to set up the registers accordingly and understand the selected parameters.

This example will focus on using the timer in CTC mode that stands for Clear Timer on Compare Match.

soon…