/*
1. Select the normal operation and CTC mode for timer0
2. Pre-scale the internal clock by a factor of 1024
3. Store the desired value (94) in OCR0A
4. Timer0 operates and increments values into TCNT0 register
5. Monitor the OCF0A flag to see if match occurs between TCNT0 and OCR0A.
6. Clear the OCF0A flag after each match occors by writing 1 to it.
7. Repeat from step 5 for 100 times.
8. Toggle the LED connected to PB1 every 1 second.
Really like the coding style with this by creating a timer function based on 1 milisecond
intervals.
See similar sketch for ATtiny13a
/Documents/Arduino/ATtiny13A/C Examples/Timer Counter Examples/Timer_and_Compare_Match/
*/
#include <TinyDebug.h>
#include <avr/io.h>
#include <avr/delay.h>
#define led1 PB3 // output
#define led2 PB4 // output
uint8_t interrupt_count = 0;
void timer_compare() {
// TCCR0A – Timer/Counter Control Register A
// We want 'Mode of Operation' set to 'Normal' so COM0xx bits are set to 0
TCCR0A = 0b00000000; // set bits COM0A0(7), COM0A1(6), COM0B0(5), COM0B1(4) to 0, WGM01(1) to 0, WGM00(0) to 0
// TCCR0B – Timer/Counter Control Register B
// set the prescaler to 1024
// 8.0 MHz / 1024 = 7812 Hz, will overflow every 7812 ticks
TCCR0B |= (1 << CS00) | (1 << CS02); // prescaling with 1024
// Setting the TOIE1 bit (= Timer1 Overflow Interrupt Enabled)
// tells the timer to trigger interrupt ( ISR(TIM0_OVF_vect) ) when the timer overflows.
TIMSK |= (1 << TOIE0); // * enabling timer0 interrupt
// TIFR0 - Timer/Counter 0 Interrupt Flag Register
// Bit 1 – TOV0: Timer/Counter0 Overflow Flag
// The bit TOV0 is set when an overflow occurs in Timer/Counter0.
// TOV0 is cleared by hardware when executing the corresponding interrupt handling vector.
TIFR |= (1 << TOV0);
//TCNT0 = 158; // preload with value per
// Bit 7 – I: Global Interrupt Enable - or use sei()
// SREG = SREG | 0b10000000;
sei(); // * enabling global interrupt
}
// ISR is triggered every time there is an 8 bit overflow (255)
// The ISR routine looks to see if the count is 36, if not it stores the count and waits for
// the next overflow trigger.
ISR(TIM0_OVF_vect) { // Interrupt vector for Timer0
if (interrupt_count == 30) { // 30 flags = 1 sec, https://eleccelerator.com/avr-timer-calculator/
PORTB ^= (1 << PB3); //toggle on 1 sec, toggle off 1 sec
//interrupt_count = 0; // set count back to zero
}
if (interrupt_count == 40) { // 30 flags = 1 sec, https://eleccelerator.com/avr-timer-calculator/
PORTB ^= (1 << PB4); //toggle on 1 sec, toggle off 1 sec
interrupt_count = 0; // set count back to zero
}
else {
interrupt_count++; // if interrupt_count does not == 36, else statement increments count by 1
}
}
int main() {
Debug.begin();
DDRB |= (1 << led1) | (1 << led2); // set PORTB3 and PORTB4 as output
timer_compare();
while (1) {
// empty loop will run continuosly but will only respond to the internal hardware overflow condition
}
return 0;
}