/*
See: https://www.gadgetronicx.com/attiny85-timer-tutorial-generating-time-delay-interrupts/$0
Sketch assumes ATTiny85 at 8.0 MHz
Use calculator at https://eleccelerator.com/avr-timer-calculator/
** Steps to configure Timer and use 'Overflow flag' to generate delay:
1. Select the normal mode of operation for timer0
2. Prescale the internal clock by a factor of 1024
3. Wait until the TCNT0 reaches the maximum value and flag is raised.
4. Clear the TOV0 flag by writing one to it.
5. Repeat from step 3 for 63 times to achieve a time delay of 1 second.
6. Toggle the LED connected to PB1 pin.
*** Not considered a good method, code has to idle in while loop of function before being executed.
*/
#include<avr/io.h>
#define F_CPU 8000000UL
#define LED1 PB1 // output
#define LED2 PB2 // output
void timer_config() {
DDRB |= (1 << PB1) | (1 << PB2); // Set Port B, pin PB1 and PB2 as output
/*
TCCR0A – Timer/Counter Control Register A
Compare Output Mode, non-PWM Mode
COM0A1 COM0B1 COM0A0 COM0B0 Description
0 0 0 0 Normal port operation, OC0A/OC0B disconnected.
*/
TCCR0A = 0x00; // Normal mode
// TCCR0B – Timer/Counter Control Register B
TCCR0B = 0x00; // clear bits, not really needed
// CS02 CS01 CS00
// 1 0 1
TCCR0B |= (1 << CS00) | (1 << CS02); // prescaling with 1024
// TCNT0 – Timer/Counter Register - 8 bit
/*
This is a 8 bit data register at which the timer value gets stored.
Being a 8 bit register this register can hold values from 0 to 255.
Upon completion of this count in TCNT0 register timer sets the Overflow flag
*/
TCNT0 = 0;
}
/*
Using calculator, prescaling with 1024: 8.0 MHz / 1024 = 7.812 KHz (7812 Hz). This is the speed at which our timer operates now.
Time per overflow = 256 / 7812.5 ≈ 0.032768 seconds
Time taken per increment = 1 / 7.812 KHz = .000128 seconds, 128 us (microseconds)
Time taken for 0 to 255 count in TCNT0 register = 128 x 255 = 32.64ms (0.03264 seconds)
This tells us it takes 32.64ms for the timer to count to 255 and set the overflow flag or trigger interrupt.
To delay for 1 second: 1 / .03264 (32.64ms) = 30.64
*/
/*
TIFR – Timer/Counter Interrupt Flag Register
This register holds the bits which indicates the status of Timer0 peripheral.
All the bits in this registers are flag bits which will go high when a certain external event occurs.
We are interested in bit 1, TOV0 bit which is the Timer0 overflow flag.
This bit will normally read zero but when the count in TCNT0 register reaches its maximum value of 255,
this bit will be set high by hardware.
Bit 1 – TOV0: Timer/Counter0 Overflow Flag
The bit TOV0 is set when an overflow occurs in Timer/Counter0. TOV0 is cleared by hardware.
*/
void timeDelay() {
unsigned int i = 0;
while(i <= 30) { // This sets a 1 second timer delay
while((TIFR & (1 << TOV0)) == 0); // Waiting for TCNT0 register to reach 255, flag to raise, TOV0 changes to 1
TIFR |= (1 << TOV0); // Clear the flag
i++; // increment by one
}
}
int main() {
timer_config();
while(1) {
PORTB |= (1 << LED1); // PORTB3 high
PORTB &= ~(1 << LED2); //PORTB4 low
timeDelay(); // Delay of 1 second
PORTB &= ~(1 << LED1); //PORTB3 low
PORTB |= (1 << LED2); // PORTB4 high
timeDelay(); // Delay of 1 second
}
}