/*
What is a timer?
Provides control of frequency of a square wave signal
generated at the OC0A/OC1A or OC0B/OC1B pins.
The square wave (ticks) can be counted.
OCF0A flag in the TIFR0 register is set when the compare value is matched.
We can then poll how many times the flag is set.
Configure Timer0 in CTC mode so that:
1. The timer resets automatically on a match (no overflow counting)
2. A Compare Match interrupt toggles an LED
3. The interval is precise and easy to adjust using OCR0A
Blink LED every 100 ms using CTC (Timer0)
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <TinyDebug.h>
#define LED0 PB0
#define LED1 PB1
volatile uint16_t match_count = 0;
volatile uint8_t ISR_done = 0;
ISR(TIMER0_COMPA_vect) {
match_count++;
if (match_count >= 2000) { // 2000 × 1ms = 2000ms
match_count = 0;
ISR_done = 1;
}
}
// Function declaration
void CTC_Mode();
int main(void) {
Debug.begin();
DDRB |= (1 << LED0) | (1 << LED1); // Set LED pin as output
CTC_Mode();
while (1) {
if (ISR_done) {
Debug.print("if start: "); Debug.println(ISR_done);
PORTB ^= (1 << LED0);
PORTB ^= (1 << LED1);
ISR_done = 0;
Debug.print("if end: "); Debug.println(ISR_done);
}
}
}
void CTC_Mode() {
// ==== TIMER0 in CTC MODE ====
TCCR0A = (1 << WGM01); // Set CTC mode (WGM01 = 1, WGM00 = 0)
TCCR0B = (1 << CS01) | (1 << CS00); // Prescaler = 64 (CS01 and CS00)
// 8000000 / 64 = 125000
// 1 / 125000 = .000008 seconds or .008 miliseconds per tick
// 1 milisecond (0.001 second) 1ms = 1 / .008 = 125
OCR0A = 125; // Compare match every 1ms (1000 Hz)
TIMSK |= (1 << OCIE0A); // Enable Timer0 Compare Match A interrupt
sei(); // Enable global interrupts
}