Wednesday, January 04, 2012

avr14

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 TIMERs.
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 ...