Hello folks! Welcome back! In this tutorial, we will come across TIMER1 of the AVR. I hope that you have read and understood the previous posts:
So basically, in this tutorial, we will do whatever we did in the previous one. In the TIMER0 tutorial, we generated a timer running at the CPU frequency. We then modified the code to include prescalers, and once again modified the code to include interrupts.
Now that you are aware of the concepts, we will deal with TIMER1 in a short and snappy way. Whatever we did in the previous TIMER0 tutorial, we will do the same here. Thus, we will discuss only one problem statement which will include both, prescalers and interrupts.
Once we are done with this, we can proceed to the CTC and PWM modes of operations in subsequent posts.
Problem Statement
Okay, let’s make it loud and clear. We need to flash an LED every 2 seconds, i.e. at a frequency of 0.5 Hz. We have an XTAL of 16 MHz.
Methodology – Using prescaler and interrupt
Okay, so before proceeding further, let me jot down the formula first.
Given that we have a CPU Clock Frequency of 16 MHz. At this frequency, and using a 16-bit timer (MAX = 65535), the maximum delay is 4.096 ms. It’s quite low. Upon using a prescaler of 8, the timer frequency reduces to 2 MHz, thus giving a maximum delay of 32.768 ms. Now we need a delay of 2 s. Thus, 2 s ÷ 32.768 ms = 61.035 ≈ 61. This means that the timer should overflow 61 times to give a delay of approximately 2 s.
Now it’s time for you to get introduced to the TIMER1 registers (ATMEGA16/32). We will discuss only those registers and bits which are required as of now. More will be discussed as and when necessary.
TCCR1B Register
The Timer/Counter1 Control Register B- TCCR1B Register is as follows.
Right now, only the highlighted bits concern us. The bit 2:0 – CS12:10 are the Clock Select Bits of TIMER1. Their selection is as follows.
Since we need a prescaler of 8, we choose the third option (010).
TCNT1 Register
The Timer/Counter1 - TCNT1 Register is as follows. It is 16 bits wide since the TIMER1 is a 16-bit register. TCNT1H represents the HIGH byte whereas TCNT1L represents the LOW byte. The timer/counter value is stored in these bytes.
TIMSK Register
The Timer/Counter Interrupt Mask Register – TIMSK Register is as follows.
As we have discussed earlier, this is a common register for all the timers. The bits associated with other timers are greyed out. Bits 5:2 correspond to TIMER1. Right now, we are interested in the yellow bit only. Other bits are related to CTC mode which we will discuss later. Bit 2 – TOIE1 – Timer/Counter1 Overflow Interrupt Enable bit enables the overflow interrupt of TIMER1. We enable the overflow interrupt as we are making the timer overflow 61 times (refer to the methodology section above).
TIFR Register
The Timer/Counter Interrupt Flag Register – TIFR is as follows.
Once again, just like TIMSK, TIFR is also a register common to all the timers. The greyed out bits correspond to different timers. Only Bits 5:2 are related to TIMER1. Of these, we are interested in Bit 2 – TOV1 – Timer/Counter1 Overflow Flag. This bit is set to ’1′ whenever the timer overflows. It is cleared (to zero) automatically as soon as the corresponding Interrupt Service Routine (ISR) is executed. Alternatively, if there is no ISR to execute, we can clear it by writing ’1′ to it.
Code
Now that we are aware of the methodology and the registers, we can proceed to write the code for it. To learn about I/O port operations in AVR, view this. To know about bit manipulations, view this. To learn how to use AVR Studio 5, view this. To learn how this code is structured, view the previous TIMER0 post.
#include <avr/io.h>
#include <avr/interrupt.h>
// global variable to count the number of overflows
volatile uint8_t tot_overflow;
// initialize timer, interrupt and variable
void timer1_init()
{
// set up timer with prescaler = 8
TCCR1B |= (1 << CS11);
// initialize counter
TCNT1 = 0;
// enable overflow interrupt
TIMSK |= (1 << TOIE1);
// enable global interrupts
sei();
// initialize overflow counter variable
tot_overflow = 0;
}
// TIMER1 overflow interrupt service routine
// called whenever TCNT1 overflows
ISR(TIMER1_OVF_vect)
{
// keep a track of number of overflows
tot_overflow++;
// check for number of overflows here itself
// 61 overflows = 2 seconds delay (approx.)
if (tot_overflow >= 61) // NOTE: '>=' used instead of '=='
{
PORTC ^= (1 << 0); // toggles the led
// no timer reset required here as the timer
// is reset every time it overflows
tot_overflow = 0; // reset overflow counter
}
}
int main(void)
{
// connect led to pin PC0
DDRC |= (1 << 0);
// initialize timer
timer1_init();
// loop forever
while(1)
{
// do nothing
// comparison is done in the ISR itself
}
}
So folks, this is how to apply the basic timer concepts for TIMER1. Please note that if you learn the basics, everything will be easy. If you find yourself struggling with the code, then please visit the TIMER0 tutorial, clear your concepts and give it a try again. If still you don’t get it, I will be glad to help you!
In my next post, we will learn how to apply the same concepts to TIMER2. It is, once again, an 8-bit timer. Thus all the TIMER2 registers are similar to TIMER0. After that, we move towards the interesting part, the Clear Timer on Compare (CTC) mode!
Till then, grab the RSS Feeds or subscribe to my blog to stay updated! Also, post your responses below. I am awaiting for them!





Can you plz help me sir
i enabled a timer in CTC mode for 60 seconds…after 60 seconds it will go into ISR and generate 4 waveform at each different pins each having 250 ms(125 on time and 125 0ff time) time(i used _delay_ms()for it)..now for second time this time(250ms*4=1sec)should be added into the next 60 seconds interval….means time for which my ISR executes should be added in the next 60 seconds interval….
my code is….
Code: http://pastebin.com/17ajaxjN
But now, first time i get waveform after 60 sec..for second time i get after 61 sec..for 3rd time i get after 62 sec..but i dont want this…i want exact 60 seconds it doesnt metter that for how much time my ISR executes…please help me….actualy i have to operate 4 watch's minute's niddle simultaneously…so timimg is very important concern….
one thing i wanna clear that i dont want to use this _delat_ms()…i dont know a lot about it…i want to use timer….
for 60 seconds delay…i used a conditional if statement in in ISR…i used 1MHZ clock with prescale 64…so my timer clock frequency is 15625…to get 1 sec delay i have to load 15624 in timer 1…bt with the same frequency,if i use another timer then there are 2 cases…..
1.. for same timer clock if i calculate the desired value for 250 ms then it will be 3906…but i have only 1 16 bit timer…timer0 and timer 2 both are 8 bit so i can use them……
2.can i use both channels A and B of timer1 as 2 different timers….
plz help me…..i m fully confused
hi mayank,
i am using ATtiny 4. i want led on for 5 ms and toggling after that. i have developed code but i am not able to do. could you please check. i have f_cpu=8 mhz with no prescaller=1.
i am not able to view on simulator.i have started my timer from 0xfffa to check fast via simulation.
Code can be found here.
Hi Amey,
You say that you are not able to view it in the simulator. What error do you get actually?
Hi Mayank
I am working Atmega128 with 16MHz external clock. Now i need to use timer, where I can wait for user input via keypad for some time say 10 secs. After that microcontroller should get reset. Please tel me how to make use of timer here. Thank u.
Hi Sanjeev
Well, this is quite simple. There are two ways.
1. Use Watchdog timer (WDT) of 10 secs. WDT is inbuilt in almost all microcontrollers. If the WDT doesn’t get any signal from the program within the stipulated time, it resets the program. So this fits the best. WDT can be enabled and set up using some bits in the AVR WDTCR register. View this tutorial to learn how to do it.
2. Create a timer of 10 secs. After that, you can send a LOW signal to the physical reset pin of your microcontroller. Use a RC arrangement (like shown here) to avoid half-reset conditions.