- 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.
- 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.
- Simply generate an interrupt and call our handler.
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) |
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
|
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 asF(timer)=16000000/64 = 250000Hz
so timer will increment its value @ 250000Hz
The setting for this is
CS12
|
CS11
|
CS10
|
0
|
1
|
1
|
TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);
TIMER Counter 1 (TCNT1)
TCNT1H (high byte) TCNT1L(low byte). This is the 16 Bit counterOutput 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
|
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 !