The simplest mode of operation is the Normal mode (WGM0[2:0] = 0x0). In this mode, the counting direction is always up (incrementing), and no counter clear is performed. The counter simply overruns when it passes its maximum 8-bit value (TOP=0xFF) and then restarts from the bottom (0x00). In Normal mode operation, the Timer/Counter Overflow flag (TOV0) will be set in the same clock cycle in which the TCNT0 becomes zero. In this case, the TOV0 flag behaves like a ninth bit, except that it is only set, not cleared. However, combined with the timer overflow interrupt that automatically clears the TOV0 flag, the timer resolution can be increased by software. There are no special cases to consider in the Normal
mode, a new counter value can be written any time.
The output compare unit can be used to generate interrupts at some given time. Using the output compare to generate waveforms in Normal mode is not recommended since this will occupy too much of the CPU time.
The counter will always count from 0 to 255 and then after 255 it will set the overflow bit and start the counting from 0.
Without Interrupt
We can use this to generate delays. But This is a type of blocking code.
/*
* main.c
*
* Created: 7/9/2023 12:47:23 AM
* Author: abhay
*/
#define F_CPU 16000000UL
#include <xc.h>
#include <util/delay.h>
void T0delay();
int main(void)
{
DDRB |= (1<<5);
PORTB |= (1<<5);
while(1)
{
PORTB |= (1<<PINB5);
T0delay();
PORTB &= ~(1<<PINB5);
T0delay();
//TODO:: Please write your application code
}
}
void T0delay()
{
/*
F_CPU/prescaler = clock for timer
1/clock for timer = timer step time
for 1 second the timer will take : 1/timer step time
16000000/1024 = 15625 clock
1/15625 = 0.000064 = 64us (counter step size)
64us x 256 = 0.016384 sec (0verflow time)
64us x 255 - tcnt +1 = 0.016384 sec (0verflow time)
64us x (255 - tcnt +1 )= x
tcnt = x / 64us ) -256
for 1 sec Delay
=> 1/0.016384 sec = 61.03515625
Taking only integer
so 61 overflows needs to occur for 0.999424 Seconds
1-0.999424 = 0.000576 seconds
0.000576/ (counter step size) = required steps
0.000576/0.00064 = 9 steps
Note: this will be close to 1 second. but it will be longer due to overhead added by the instructions.
*/
for(int i = 0; i< 61;i++){
TCNT0 = 0;
TCCR0A = 0;
TCCR0B |= (1<<CS00)|(1<<CS02); //prescaler 1024
while( (TIFR0 & 0x1) == 0); // Wait for overflow flag
TCCR0B = 0;
TIFR0 = 0x1;
}
//9 steps timer code
TCNT0 = 255-9;
TCCR0A = 0;
TCCR0B |= (1<<CS00)|(1<<CS02); //prescaler 1024
while( (TIFR0 & 0x1) == 0); // Wait for overflow flag
TCCR0B = 0;
TIFR0 = 0x1;
}
Normal Mode with Interrupt
#define F_CPU 16000000UL
#include <xc.h>
#include <avr/interrupt.h>
ISR(TIMER0_OVF_vect){
PORTB ^= (1<<PINB5); // Toggle the GPIO
}
int main(void)
{
DDRB |= (1<<5); // set Data direction to output for PB5
PORTB |= (1<<5); // set output to high
TCNT0 = 0;
TCCR0A = 0; // Normal Mode
TCCR0B |= (1<<CS00)|(1<<CS02); //prescaler 1024
TIMSK0 |= (1 << TOIE0); // Overflow Interrupt Enable Bit
sei(); // Enable Global Interrupt
while(1)
{
//TODO:: Please write your application code
}
}
Leave a Reply