1.
Timers and Counters
·
Timers
and Counters are the one of the most commonly used complex peripheral in a
microcontroller.
·
They are
used for getting time periods, generating pulse signals and also for measuring
time period of pulses.
·
There
are two main TIMER/COUNTER in ATMEGA32 : TIMER0(8-Bit) and TIMER1(16-Bit)
·
Timer0
will roll over after 255 and Timer1 will rollover after 65,535. So be careful
about this roll over when using Timers in a µC.
·
TCNT0 is
the counter for TIMER0 ie. It is like a variable which counts with the
oscillation of system clock and rolls over back to 0.
·
Similarly
TCNT1 is the counter for TIMER1.
Timer0:
Using timer 1 includes setting the appropriate
values in the Timer Counter Control Register mainly for setting the speed /
frequency at which TCNT0 is counting.
Program:
#include <avr/io.h>
#include <util/delay.h>
#include<avr/interrupt.h>
void main()
{
DDRB
= 0b00000011;
PORTB
= 0b00000000;
TCCR0
= (1<<CS02) | (0<<CS01) | (1<<CS00); // 8MHz / 1024 as prescaler
TCNT0
= 0;
int
ctr1 = 0;
int
sec_ctr = 0;
while(1)
{
if(TCNT0
== 200)
{
PORTB
= 0b00000000;
TCNT0
= 0;
ctr1++;
if(ctr1
== 39)
{
ctr1
= 0 ;
PORTB
= 0b00000001;
sec_ctr++;
if(sec_ctr
>= 60) //checking for elapsing of one minute
{
PORTB
|= 0b00000010;
sec_ctr
= 0;
_delay_ms(10);
}
}
}
}}
·
An
interrupt is also being generated when the overflow of Timer occurs.
·
We need
to unmask the TIMER0 overflow interrupt in the TIMSK registers and should use
suitable ISRs.
·
The
previous example could be done with the help of interrupts as given below:
#include
<avr/io.h>
#include
<util/delay.h>
#include<avr/interrupt.h>
int
ctr1 = 0;
int
sec_ctr = 0;
void
main()
{
DDRB = 0b00000011;
PORTB = 0b00000001;
TCCR0 = (1<<CS02) | (0<<CS01) |
(1<<CS00);
TIMSK = 0x01; //Enabling TIM0 ovf interrupt
TCNT0 = 55;
sei();
int ctr1 = 0;
int sec_ctr = 0;
OCR0 = 0;
while1)
{
//Do nothing…
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0 = 55;
PORTB = 0b00000000;
ctr1++;
if(ctr1 == 39)
{
ctr1 = 0 ;
PORTB = 0b00000001;
sec_ctr++;
if(sec_ctr >= 60) //checking for
elapsing of one minute
{
PORTB |= 0b00000010;
sec_ctr = 0;
_delay_ms(10);
}
}
}
TIMER1:
·
Timer1 is a 16 bit counter and rolls over occur
after 65535.
·
Here the Timer Counter Control Registers are
TCCR1A and TCCR1B
·
We will be using here just TCCR1B for setting
the prescaler bits.
Program:
Source: www.newbiehack.com
#include <avr/io.h>
int main(void)
{
DDRB = 0b01111111;
PORTB = 0b00000000;
DDRD = 0b01111111;
PORTD = 0b00000000;
TCCR1B |= 1<<CS10 | 1<<CS11;
int LEDNumber[2];
while(1)
{
if (TCNT1 > 2232)
{
TCNT1 = 0;
PORTB = 1<<LEDNumber[0];
LEDNumber[0] ++;
if (LEDNumber[0] > 6)
{
LEDNumber[0] = 0;
PORTD = 1<<LEDNumber[1];
LEDNumber[1] ++;
if (LEDNumber[1] > 6)
LEDNumber[1] = 0;
}
}
}
}
·
We
could also do this thing using interrupts:
Source: www.newbiehack.com
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
sei();
DDRB |= 1<<PINB0;
TCCR1B |= 1<<CS10 | 1<<CS11 | 1<<WGM12;
TIMSK |= 1<<OCIE1A;
OCR1A = 15624;
while(1)
{
}
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= 1<<PINB0;
}