Hi Friends,

In last tutorials we discussed about the basics of TIMERs of AVR. In this tutorial
we will go a step further and use the timer in compare mode .
In our first tutorial on timer we set the clock of the timer using a prescaler
and then let the timer run and whenever it overflowed it informed us. This way
we computed time. But this has its limitations we cannot compute time very accurately.
To make it more accurate we can use the compare mode of the timer. In compare
mode we load a register called Output Compare Register with a value of our choice
and the timer will compare the current value of timer with that of Output Compare
Register continuously and when they match the following things can be configured
to happen.

  1. A related Output Compare Pin can be made to go high,low or toggle automatically.
    This mode is ideal for generating square waves of different frequency.
  2. It can be used to generate PWM signals used to implement a DAC digital to
    analog converter which can be used to control the speed of DC motors.
  3. Simply generate an interrupt and call our handler.

On a compare match we can configure the timer to reset it self to 0. This is
called CTC – Clear Timer on Compare match.

The compare feature is not present in the 8 bit TIMER0 of the ATmega8 so we
will use the TIMER1 which is a 16 Bit timer. First we need to setup the timer’s
prescaler as described in the Timer0 tutorial.
Please
see this tutorial for a basic introduction of TIMER
s.

The TIMER1 has two compare units so it has two output compare register OC1A
and OC1B. The ’1′ in the name signifies that they are for timer ’1′.

In this tutorial we will create a standard time base which will be useful for
many projects requiring timing such as clocks,timers,stopwatches etc. For this
we will configure the timer to generate an Compare match every millisecond and
in the ISR we will increment a variable clock_millisecond. In this way we will
have a accurate time base which we can use for computing time in seconds,minutes
and hours.

References

For
learning about the basic idea of peripherals and their use with AVRs please
see this tutorial.

For
learning about basics of timers see this.

AVR’s Timers1 Registers

I will state the meaning of only those bits which are required for this tutorial.
These bits are marked with a gray back ground in the table. For details about
other bits please consult the datasheets.

Timer/Counter1
Control Register A (TCCR1A)

This register is used to configure the TIMER1. It has the following bits

Bit

7

6

5

4

3

2

1

0

Name

COM1A1

COM1A0

COM1B1

COM1B0

FOC1A

FOC1B

WGM11

WGM10

InitialValue

0

0

0

0

0

0

0

0

COM1A1 and COM1A0 -

This are used to configure the action for the event when the timer has detected
a "match". As i told earlier the timer can be used to automatically
set,clear or toggle the associated Output compare pin this feature can be configured
from here. The table below shows the possible combinations.

COM1A1

COM1A0

Description

0

0

Normal Port Operation (The timer doesn’t touches the PORT pins).

0

1

Toggle OC1A Pin on match

1

0

Clear OC1A on match – set level to low (GND)

1

1

Set OC1A on match – set level to High(Vcc)

The OC1A pin is the Pin15 on ATmega8 and Pin19 on ATmega16/32. As you may guess
that we don’t need any pin toggling or any thing for this project so we go for
the first option i.e. Normal Port Operation

As I have told you that the TIMER1 has two compare unit, the COM1B1/COM1B0
are used exactly in same way but for the channel B.

WGM11 and WGM10 -

These combined with WGM12 and WGM13 found in TCCR1B are used for selecting
proper mode of operation. WGM= Waveform Generation Mode.

Timer/Counter1
Control Register B (TCCR1B)

This register is also used for configuration. The Bits are.

Bit

7

6

5

4

3

2

1

0

Name

ICNC1

ICES1

-

WGM13

WGM12

CS12

CS11

CS10

InitialValue

0

0

0

0

0

0

0

0

The four bits

WGM13 – WGM12 – WGM11 – WGM10 are used to select the proper mode of operation.
Please refer to the datasheet for complete combinations that can be used. We
need the CTC mode i.e. clear timer on match so we set them as follows

WGM13=0

WGM12=1

WGM11=0

WGM10=0

This is the settings for CTC.

The CS12,CS11,CS10

These are used for selecting the prescalar value for generating clock for the
timer. I have already discussed them on TIMER0 tutorial.
I will select the prescalar division factor as 64. As the crystal we are using
is of 16MHz so dividing this by 64 we get the timer clock as

F(timer)=16000000/64 = 250000Hz

so timer will increment its value @ 250000Hz

The setting for this is

CS12

CS11

CS10

0

1

1

So the final code we write is

TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);

TIMER
Counter 1 (TCNT1)

TCNT1H (high byte) TCNT1L(low byte). This is the 16 Bit counter

Output
Compare Register 1 A – OCR1A (OCR1AH,OCR1AL)

You load them with required value. As we need a time base of 1ms and our counter
is running @ 250000Hz i.e. one increment take 1/250000 = 0.000004 Sec or 0.004
ms. So we need 1ms/0.004 = 250 increments for 1ms. Therefore we set OC1A=250.
In this way when timer value is 250 we will get an interrupt and the frequency
of occurrence is 1ms and we will use this for incrementing a variable clock_millisecond.

Output
Compare Register 1 B – OCR1A (OCR1BH,OCR1BL)

 

Timer
Counter Interrupt Mask (TIMSK)

This is the mask register used to selectively enable/disable interrupts. This
register is related with the interrupts of timers (all timers TIMER0,TIMER1,TIMER2).

Bit

7

6

5

4

3

2

1

0

Name

OCIE2

TOIE2

TICIE1

OCIE1A

OCIE1B

TOIE1

-

TOIE0

InitialValue

0

0

0

0

0

0

0

0

Of all these bits 5,4,3,2 are for TIMER1 and we are interested in the OCIE1A
which is Output Compare Interrupt Enable 1 A. To enable this interrupt we write

TIMSK|=(1<<OCIE1A);

After enabling the interrupt we also need to enable interrupt globally by using
the function

sei();

This function is part of AVR-GCC interrupt system and enables the interrupt
globally. Actually this translate in one machine code so there is no function
call overhead.

So friends that’s its for now ! The rest will be covered in latter tutorials.
To get all the latest tutorials on your mailbox subscribe to my RSS feed via
e-mail.

And don’t forget to post your comment !!! What you think about them and what
you will like to see here. Or simply post any doubt you have about this tutorial.

Goodbye, and have fun !

Move On …