Pages Menu
TwitterRssFacebook
Categories Menu

Posted by on Jun 28, 2011 in Atmel AVR, Microcontrollers | 90 comments

AVR Timers – TIMER1

AVR Timers – TIMER1

AVR SeriesHello 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.Timer CountGiven 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.

TCCR1B Register

TCCR1B Register

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.

Clock Select Bits Description

Clock Select Bits Description

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.

TCNT1 Register

TCNT1 Register

TIMSK Register

The Timer/Counter Interrupt Mask Register – TIMSK Register is as follows.

TIMSK Register

TIMSK Register

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.

TIFR Register

TIFR Register

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! :)

Max

Max is the founder and admin of maxEmbedded. He describes himself as an 'embedded electronics freak' and an Apple/Linux fan. He likes to experiment, learn and share new things in this field. Furthermore, he likes to write stuffs on his website for techie newbies and loves to teach others. In his spare time, you will find him with volunteering somewhere!

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle Plus

90 Comments

  1. Hello, Mayank!

    I have been reading your tutorials and still couldn’t find a couple of questions I have regarding certain aspects of a project I am working on. It consists in designing a quitar tuner, for which I used the ATmega16-DIL40 processor, with an ISP programming connector and MAX232 level convertor. The hardware part was the easiest one, but in terms of programming, it is not clear how the AVR code should look like.
    The functioning principle of a tuner is based on each chord frequencie comparison to the standard one. I want my system to light a green LED when the chord is below the standard frequency, a red LED when higher, and both of them when in standard.
    So, could you, please, give me an example or any details on how this is done in AVR?
    Should you need any other info, e-mail me at adelatitescu@yahoo.com.
    Thanks!
    Adela

    • Hi Adela,

      What you need to do is to design a Digital Filter using AVR. Before proceeding, I would like to ask you what is your background? Are you familiar with Digital Signal Processing? Cuz if you are, then you might be able to follow this application note.

      AVRs are not designed operate as digital signal processors. They are not designed to operate with high frequency signals like those of music/audio. However I am sure that you can create simple 2nd or 3rd order filters using them. I haven’t designed filters on an AVR before (I designed them on Digital Signal Processors like the TMS320C6713 DSP by Texas Instruments), but I know a friend of mine who designed a 1st order filter in an AVR, and I have also seen people implementing simplified form of Kalman Filter using AVR. Its just a simple code, with some nested loops, and equations with calculated coefficients.

      Maybe I could help you out with it, but only if you understand some DSP.

      • Mayank,   I am familiar with DSP, but only in Math-Lab regarding aspects… For my project, I believe a 2nd order filter would do, but I still need an example of how this can be done using AVR. Perhaps the 1st order application of your friend’s is a good one…?

        Thanks, Adela

        ________________________________

        • Hi Adela,

          I can give you a basic idea about the code, but you still need to search more.

          1. Take in your audio signal using the ADC and store it in a register. Usually the ADC register is either 8 bits or 10 bits long. I would prefer to use one register of 8 bits. You can refer to my ADC tutorial regarding it, remember to set ADLAR bit so that you get the 8 bit ADC result.
          2. Then you need to implement a digital filter equation. I would prefer an FIR filter instead of an IIR filter since FIR has limited coefficients. Check this out, there they give you a basic idea about these equations. Depending upon the order of the filter, your coefficients vary. You will need to compute your coefficients. Once your equation is ready, you will need to implement using C code. If the equation involves summation, then you will have to do it within (nested) loops.
          3. After applying the filter, if you get a measurable output, then it has gone through, or else it hasn’t. You can easily check them and light up LEDs if you want.

          I would highly suggest you to post your query to the Forums of avrfreaks.net since you will get expert help and support there. Even my knowledge in DSP is quite limited, since I am a hardware guy not a mathematics guy. ;)

          Thanks,
          Mayank

  2. TIFR: “Alternatively, if there is no ISR to execute, we can clear it by writing ’1′ to it.”

    Do you mean “…by writing ‘0’ “?? Thank you.

    • Hi George,
      Nope, we clear it by writing “1” (and not “0”). Strange, right? But the architecture of AVR is such that if we need to clear a flag, we need to write “1” to it. That’s what it is written in the datasheet.

  3. “Thus, 2 s ÷ 32.768 ms = 61.035 ≈ 61.”. Well, why 61 and not 60? Thank you.

  4. Comment on my 2nd question: 61 is the right value and not 60. It seems that I would see 60.035. Sorry!!!!! Great job!!!

  5. Hy ! I have to design a digital minipiano but have no ideea about some stuf:
    1- can I make speaker sing without PWM only with timer( i must to play c d e f g h a b c)
    2-how can i switch between the time play ( 1 second or 2 seconds per note)
    Thanks!

    • Hello sOUNDgen,
      Well, it actually depends how are you generating the sound. PWM seems to be a simple idea, but I guess you can use timers as well. But to give you more info, I need to know how do you plan on generating the piano sounds and different notes (like CDEF…)

      To switch between the time play, you can use timers to create a delay, or simply use _delay_ms().

      Best,
      Max

      • I use keyboard ps2 to choose one from the 8 notes . I have the frequency for all the notes but i don t know how to transmit it to the Digilent Speaker module. For the delay my problem is that i must to write my code in assembly thats why i believe that i must choose different prescalers for the time change

        • Just connect the PWM pins of the AVR to the left, right or both the terminals of the speaker module, and that should do it.
          I don’t quite understand what you need the delay for. Please elaborate on that.
          Hope this helps! :-)

  6. hy mayank sir this code is not running condition which you are given..

    • Hasham,
      I have two things to say. First, so what? So what if it doesn’t work? I have taught you the concept above, go fix it yourself! Second, it works! It has worked for everyone else, why shouldn’t it work for you? Did you try the Timer0 code? If it worked, this should also work. If that doesn’t work, get back to me! Thanks!

      • sir i am bigginer in AVr…can you explain tne above code in detail.for example why we use while loop at the bottom..but in timer0 we use while loop in middle?

        • Hasham,
          If you are a beginner in AVR, what makes you directly look into the code? Frankly speaking, I’m pissed off by this question of yours! Go read some basics man. Check out the index page and start reading the tutorials one by one, and you’ll get the answer to your question. And I hope that you are familiar with C. If not, STOP and look elsewhere to learn it first. Thanks!

    • Try placing the comparison statment
      http://pastebin.com/ySmJMnxn
      within the while loop in main() instead of implementing it within the ISR. It didnt work for me with the code inside the ISR, but once placed it within the while() loop things worked perfectly.

      I dont know why its behaving this way. I initially suspected that this has something to do with optimisation. I tried with the no optimisation option but still the program didnt work.

      I know its too late for a reply, but this is in the hope that it will be useful for someone else in future :)

  7. I am looking for information “C codes” on “How to start and stop TIMER1″ on PIC16F684 and use the time elapsed to trigger other events. Timer1 writes to two “8 bit” registers “TMR1H:TMR1L register pair”. I have configured T1CON with Internal clock, but “T1G” is not triggeriing to start the clock and it is not incrementing. Any assistance is appreciated.

  8. sir.. really an impressive and amazing work you are doing here ! Please bare with me asking these silly doubts to you (:P) i am not quite clear on this internal and external oscillator concept.. i understand that if i attach a crystal oscillator externally to XTAL pins of the controller, then it is external oscillator, but what does Internal osc mean ? ? [1st question]
    Also, apart from
    #ifndef F_CPU
    #define F_CPU 1000000UL
    #endif
    this if there is something else I should be concerned about when I use an external oscillator or just the above mentioned three lines of code will do the work ? [2nd question]
    Will I be able to run the controller without connecting this external crystal oscillator [ re framing the same question – Will the controller run just with my internal oscillator ? [3rd question]
    If Yes, I would be grateful if you could answer the following two questions.
    1.) the changes that I have to do in any of the registers before starting to write the codes ?
    2,) Amongst the various internal clocks that are available inside a controller how do I know which clock will be used to execute the program, am asking this because, only if i know this information i will be able to calculate the delay period of the timer required. Does my question make sense to you sir?
    if you could at least hint me with your reply so that I can Google and find out the complete answer. Thanks a ton :)

    • Hello Sudharsan,
      Two things. One, next time, please try to put forth your ideas in a better way. Two, no question is silly or stupid. Questions arise because you’re trying to understand stuffs, unlike those who don’t ask questions.

      Now coming to your questions.
      1. Internal oscillator is the inbuilt clock in your microcontroller.
      2. You may also need to set proper fuse bits, which depends upon the type of microcontroller you are using.
      3. Yes, why not?
      3.1. See answer 2 above.
      3.2. Can you list all the internal clocks of an AVR?

      • Sure, I ll try improving.
        3.2 – Sorry sir, I thought there were more than one internal clock. I suppose, I got it now. Thank You.

        • In some microcontrollers, there are more than 1 internal clock, but they are derived from the one and only one master clock nonetheless. An example is the MSP430. In AVR, you don’t have to worry about that. Just set the proper fuses, and it follows the internal F_CPU on its own.

          • that is where i got mistaken.. anyways Ty sir :)

          • Hi Mayank,

            Thank you for getting back with me on this. I have tried setting the TIMER1 on 16F684 and 18F2525 according to the instructions of each PIC Data Sheet. I am using the “8MHZ” internal clock, the registers are set up such as “T1CON” are configured, see below . However, after compiling code with “MiKroElectronica”, the two data registers “TMR1H , TMR1L” are not getting updated and during the “debug” I am not seeing anything being written or changed in these two “8 bit” registers when I step through the codes. http://pastebin.com/DEj0tQSk

            Any help is appreciated.

            Regards,
            Givi

          • Hi Givi,
            Did you try running it in real hardware? Simulators many a times are not able to model clock operations properly, and hence either don’t work or provide inaccurate results.

            Btw, if you wish to set a particular bit, try using something like T1CON |= 0x01; and if you wish to clear a particular bit, use something like T1CON &= ~0x01; This technique is called bit masking, and is considered a good practice.

          • Hi Mayank,

            Thank you for getting back with me on this, I appreciate it very much. I don’t have a simulator, but I can burn a PIC quick and test in real time. I will test with “bit masking” technique that you suggested and I think that is a good idea. I’ll keep you informed of what I’ll find out.

            Thanks again. Anything else please let me know.

            Regards,

            Givi

  9. http://pastebin.com/JxxKtSdn
    can you please explain me the line by line explanation of the code by commenting.it wud be of great help to me my project review is after few days and i dont know few parts of the code.i have read all ur tutorials,i found it helpful in many cases.my project is vehicle performance tester where i am going to check acceleration and decceleration and co tessting.i am not understanding how have they used pwm to measure acceleration.please explain it to me if possible

    • No. I can’t. We don’t help out with homeworks. Is this some kind of joke or something, that you throw your long code at me and ask for line by line explanation? It’s your project, you should have written the code. If not, I don’t care for people who copy codes without understanding and ask for help few days before their review. If you state that you’ve read all my tutorials and asks such a question, then there are two possibilities- one, that you are a dumb moron, or two, you haven’t read through my website. Go and ask the one who has written this code.

      I am sorry for such a coarse language, I didn’t mean to offend you, but it boils my blood when people ask questions without even reading what’s in here. Good luck for your review.

      PS. You cannot use PWM to measure something. Acceleration is an analog quantity, and to measure that, you need to feed it through the ADC input pin. PWM is supposed to be an output. Please read related articles on my website for more information. Thanks.

      • mayank,i have read your tutorials,i dont need to fake anything.I read the entire timer part,the thing is that in my project i am going to develop a small prototype of a wheel moving which is controlled by a motor and i want to calculate the acceleration,decceleration and the carbon monooxide detection..as this is a prototype,we will just show it for representational purpose and not on actual vehicle..so i am unsure about how to calculate the velocity of vehicle using timer of the avr,also in acceleration i wud want to increase the speed gradually from a certain speed to a certain speed example(0 to 50) i wud want to know how the timer will exactly solve its purpose…i did not take code from anybody i found it online..wanted to know if im thinking right..i sent u the whole code but i dint understand bits of it…if you could please help me how to determine the acceleration and velocity by using the timer it would be of great help. the wheel i am going to use is a small plastic wheel with 8 holes..so on the internet i read some concept that if you use an ir sensor transmitter on one side of the wheel and reciever on the other….so when the pulses from the sensor cuts the hole of the wheel the timer should be updated,in this way if 8 pulses are cut one circumfurence of the wheel is covered and in such a way you can calculate the velocity,but im not able to apply it in coding…if you can help me with any idea about both velocity and accelration i would be thankful.

        • Anand,
          In order to measure in speed/acceleration using the way you have mentioned, you can try out something like this:
          http://pastebin.com/fTa1jhx2

          You’ll have to detect the positive edge (if active high, or negative edge if active low) of the input (sensor), and then increment a counter. When the counter reaches 7, you know it’s time for reset and that you have already finished one rotation. There are two ways to do this – polling and interrupt. Polling is simple, whereas interrupt-driven method is more efficient. I am yet to cover the interrupt tutorial on mE, so till then you can refer to the datasheet of the microcontroller you are using.

          • Hi Mayank,

            Thank you for thinking of me. Yes after some thinking I was can agree with you. I may have to use a different processor such as PIC-16F877A. But I will let you know how it’s going to work out. Please keep in touch. Thanks again for your suggestion.

            Regards,

            Givi

  10. also i know how the timers work by ur tutorials but im not getting the exact application of it in my code.im in deep trouble as my seminar is in two days.thanks in advance :)

  11. Hi Mayank, as u suggested, -so I was able to STOP timer1 from the main(), by writing TCCR1B=0x00;, ..but..then I could not again START the timer1 (as it was before) by writing TCCR1B |=((1<<CS10)|(1<<CS12)); (pre-scaller /1024). But after stopping it,..only a re-set of the “micro-chip”, again started the timer1 as it was before..?? So, what could be the code to re-start timer1 (in Compare mode), after STOPPING it…??? ..Thanx,.Regards.

  12. sir
    i have a little bit confusion u told that 1s delay cant be generated through timer0, by prescaler u shown that timer1 is required .Is it possible to generate a delay through interrupt of 1s in timer0.

    2. in timer1 u have generated a delay of 2s by interrupt,please tell me on which basis u have chosen prescaler 8 why not prescaler 256.In timero interrupt u chose prescaler 256. i have calculated by formulae max delay is 16.32ms by pres 1024, then why u chose 4.096.

    please reply my question.

    • Hello Ravi,
      Did I? I don’t remember myself saying that you cannot generate a delay of 1s using Timer0. The question is, what frequency are you using?

      You can choose any value of prescaler, as long as you’re able to implement its functionality accurately. If F_CPU = 16 MHz, prescaler of 256 would give you a frequency of 62.5 kHz. For Timer1, max delay would be 1.048s. Thus, for 2s delay, you need to make it overflow approximately twice.

      • can u tell me how to set fuse bit if we use 16 mhz external crystal in atmega 32 …IN default it is 1 mhz .
        waiting for u arm tutorials…..

        thanks max…

        • Fuses can be programmed using your programmer itself. Which programmer are you using?

          The fuses for ATmega32 are LOW 0xFF, HIGH 0xC9. They are tested to work fine. This fuse setting disables JTAG on PORTC and enables use of external crystal. WARNING: But be extra careful during this process. If you program wrong fuses, you’ll mess up real bad!

  13. we are trying to run 2 simple dc motors at some interval such that when one motor runs another remains stationary and vice- versa.
    first we used timer1, it worked successfully only once and then we switched to delay function and here is the code which we used (cvavr code logic) :-
    http://pastebin.com/RMGxqNYr
    but this was not working on hardware but it did work on proteus.
    we are using this in roboarm.
    please suggest us some solution to this problem or any other thing which we can use as soon as possible.
    thank you…..

    • Hello,
      There could be a million reasons why it isn’t working on your hardware. I can’t state all of them. Instead, it’d be great if you could tell us what’s working, what’s not working, and what exactly have you done, so that we can suggest you something.

      Thanks,
      Max

      • actually we are trying to run two motors (after a time interval of 7 seconds) which we are going to use in robotic arm but by using the above code the circuit worked properly only on proteus but it didn’t worked on bread board. Initially we used timer1 and it did work but only once and then we switched to delay function but it didn’t worked ,then we again used timer1 and it worked. But it still is not clear that why the delay function that we used didn’t worked.
        thank you

        • You mean to say that _delay_ms() doesn’t work? So what works? Does the motor just keeps on rotating i.e. the delay is infinite?! Have you specified the value of FCPU correctly in the software? Have you used the util/delay.h header?

  14. Hi Max,

    I have a problem with my Timer1.

    I’ve followed the steps of your tutorial for the same example (Prescaler = 8 with 61 overflows to achieve 2s approx). In addition, I’ve added a serial.println(millis()) in the ISR in order to measure exactly the delay between each ISR: http://pastebin.com/gXwF5fD1

    However, the delay between each ISR is not 2s, in fact, it is very smaller (about 130ms).

    I am working with Arduino Mega 2560 , with a 16MHz clock (from Datasheet).

    Any idea of why doesn’t it work?
    Thank you very much in advance for your attention :)
    Best Regards.

    • Hi again!

      I think I’ve found the solution! It seems that the initial value of TCCR1A register was not 0x00. I’ve forced that value and now I’ve achieve 2 sec of flashing.

      Anyway, thank you very much!

      Regards :D

      • Good job Jessie! I like your debugging skills! :)

  15. Hi, I am simulating the Timer1 example in proteus 8. I am using Atmega328P_PU. My code is not lighting up the led and I wonder where or what the problem might be. The simulation with Timer0 worked perfectly but with Timer1, the simulation had no notable change rather it was not lighting the led.
    Here is my code: (code removed by admin)

    Kindly assist me in this.

    Thank you in advance.

    • Try it out in hardware. Sometimes simulators are not able to model timer properly since timer is a property of the hardware and depends upon how the hardware is configured.

  16. “The following HEADER FILES is sufficient for this program or else we have to include some more HEADRE FILES.”

    • Ajay, is that supposed to be a question? I don’t understand.

  17. hi, Thanks for the tutorial.It is really helpful. I want to ask one thing that if we use if (tot_overflow >= 61) condition in while loop ( In main function), then whether it will give any problem ?

    • Hi Anjali,
      Yes, it will be huge problem, the program won’t work! If you write the condition in the while loop in main, there will never be a time when that condition will be true since the micro-controller will reset after the main function terminates, resulting in defaulting of all registers. Basically, tot_overflow will never be able to reach 61 (or greater) since the micro-controller will always reset before it can.
      Hope this helps!

Trackbacks/Pingbacks

  1. AVR Timers – TIMER0 « maxEmbedded - [...] AVR Timers – TIMER1 « maxEmbedded [...]
  2. Introduction to AVR Timers « maxEmbedded - [...] TIMER1 – 16-bit timer [...]
  3. AVR Timers – TIMER2 « maxEmbedded - [...] AVR Timers – TIMER1 [...]
  4. AVR Timers – CTC Mode « maxEmbedded - [...] 16-bit TIMER1 [...]
  5. AVR Timers – PWM Mode – Part I « maxEmbedded - [...] AVR TIMER1 [...]
  6. AVR Timers – TIMER0 | maxEmbedded - [...] AVR, there are three types of timers – TIMER0, TIMER1 and TIMER2. Of these, TIMER1 is a 16-bit timer …

Post a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>