/*
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 (78) 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.
4. Enable Global interrupt enable I bit in SREG register
5. Enable OCIE0A bit in TIMSK register to enable Timer0 compare match interrupt.
6. Write the Interrupt service routine to repeat the operation 100 times to obtain a delay of 1 second.
7. Toggle the LED connected to the PB1 pin once the operation repeated 100 times.
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 PB1 // output
int intr_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
// Need to set bit WGM01 for CTC 'Mode of Operation'
/*
This means the timer value in TCNT0 register will count from 0 to the value in OCR0A register and once
match occurs. The timer value will roll back to zero and continue counting towards OCR0A for next cycle.
*/
TCCR0A = 0b00000010; // set bits COM0A0(7), COM0A1(6), COM0B0(5), COM0B1(4) to 0, WGM01(1) to 1, 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
// OCR0A – Output Compare Register A
// This register holds the value to be compared with TCNT0. This is a 8 bit register which holds values up to 255.
// compare value, 78 increments at .128008 Ms each tick * 78 = 9.984 miliseconds, * 100 = 998.4 ms
OCR0A= 78; // 8 bit register can hold value up to 255
// TCNT0 – Timer/Counter Register
// keeps track of overflow value, max value is 255
// 8000000 MHz / 1024 = 7812 Hz, will overflow every 7812 ticks
// 1 / 7812 = .000128008 seconds or .128008 miliseconds
// This is the time period that each count takes to increment in TCNT0 register.
// Number of steps to get to 10 milisecond (1/100 second) 10ms = 10 / .128008 = 78.12
TCNT0 = 0; // preload with value:
// TIMSK – Timer/Counter Interrupt Mask Register
// Bit 4 – OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
// The corresponding interrupt is executed if a Compare Match in Timer/Counter0 occurs,
// i.e., when the OCF0A bit is set in the Timer/Counter 0 Interrupt Flag Register – TIFR0.
TIMSK |= (1 << OCIE0A);
// Bit 7 – I: Global Interrupt Enable - or use sei()
// SREG = SREG | 0b10000000;
sei(); // * enabling global interrupt
}
ISR (TIMER0_COMPA_vect) {
if (intr_count == 100) {// waiting for 100 count because to get 1 sec compare match should occur 100 times
PORTB ^= (1 << PB1); //toggling the LED
intr_count = 0; //making intr_count=0 to continue the process
}
else intr_count ++; //incrementing intr_count
}
int main() {
Debug.begin();
DDRB |= (1 << led1) | (1 << led1); // set PORTB3 and PORTB4 as output
timer_compare();
while(1) {
// empty loop
}
return 0;
}