/*
Hardware Timer Demonstration
Arduino Uno / Nano (ATmega328P)
Timer1 generates an interrupt every 100 ms.
LED blinks once per second using timer ticks.
*/
const byte LED_PIN = 13;
volatile unsigned long timerTicks = 0;
volatile bool oneSecondElapsed = false;
ISR(TIMER1_COMPA_vect)
{
timerTicks++;
if (timerTicks % 10 == 0) // 10 x 100ms = 1 second
{
oneSecondElapsed = true;
}
}
void setupTimer1()
{
cli(); // Disable interrupts during setup
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
/*
Timer frequency calculation:
CPU = 16 MHz
Prescaler = 64
Timer clock = 16,000,000 / 64 = 250,000 Hz
For 100 ms:
250,000 * 0.1 = 25,000 counts
OCR1A = 24,999
*/
OCR1A = 24999;
// CTC mode
TCCR1B |= (1 << WGM12);
// Prescaler = 64
TCCR1B |= (1 << CS11) | (1 << CS10);
// Enable compare match interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // Re-enable interrupts
}
void setup()
{
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
setupTimer1();
Serial.println("Timer1 Demo Started");
}
void loop()
{
static unsigned long lastPrint = 0;
// Handle timer event generated by ISR
if (oneSecondElapsed)
{
noInterrupts();
oneSecondElapsed = false;
unsigned long count = timerTicks;
interrupts();
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
Serial.print("Seconds elapsed: ");
Serial.println(count / 10);
}
// Simulate other work
if (millis() - lastPrint > 250)
{
lastPrint = millis();
Serial.println("Main loop is busy...");
}
}