# Hardware Timers Overview — Arduino & Embedded C

Source: https://www.geekswithgeeks.com/en/arduino-embedded-c/hw-timers

> Counting clock ticks in hardware.

## Timers, prescalers and compare matches

A **hardware timer** is a counter driven by the system clock through a **prescaler** (a divider). When the counter matches a compare value or overflows, it can toggle a pin, generate PWM or fire an interrupt, all without CPU effort. The ATmega328P has Timer0 and Timer2 (8-bit) and Timer1 (16-bit). The Arduino core uses **Timer0** for `millis()`, `micros()` and `delay()` plus PWM on pins 5 and 6, Timer1 for PWM on pins 9 and 10 (and the Servo library), and Timer2 for pins 3 and 11 (and `tone()`). Reconfiguring a timer yourself breaks whatever relied on it. For a periodic interrupt in **CTC mode**: compare value = F_CPU / (prescaler × frequency) − 1, so 16 MHz / (1024 × 1 Hz) − 1 = 15624.

## 1 Hz interrupt with Timer1 (ATmega328P, 16 MHz)

Register names from the ATmega328P datasheet; this disables PWM on pins 9 and 10 and conflicts with the Servo library.

```cpp
volatile bool tick = false;

ISR(TIMER1_COMPA_vect) {
  tick = true;                                // keep it short
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  noInterrupts();
  TCCR1A = 0;                                 // normal port operation
  TCCR1B = (1 << WGM12)                       // CTC mode, TOP = OCR1A
         | (1 << CS12) | (1 << CS10);         // prescaler 1024
  OCR1A  = 15624;                             // 16 MHz / 1024 / 1 Hz - 1
  TCNT1  = 0;
  TIMSK1 = (1 << OCIE1A);                     // enable compare-match A interrupt
  interrupts();
}

void loop() {
  if (tick) {
    tick = false;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}
```

## Check what the core already uses

Before taking over a timer, check which libraries (Servo, tone, IR receivers) and PWM pins depend on it for your board. Conflicts show up as mysteriously broken features.

**Quiz:** On an Arduino Uno R3, which timer does millis() rely on?

- [ ] Timer1
- [x] Timer0
- [ ] Timer2
- [ ] The watchdog timer

*Answer:* Timer0. Changing Timer0 settings would break millis(), micros() and delay().
