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

About these ads

78 responses to “AVR Timers – TIMER1

  1. 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….

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

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

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

  5. Hi Sir.. i have to use timer1 of atmega32 in fast pwm mode (mode 14) for the generation of sine wave. But on timer when i set it up, i do not get the required frequency on output. my code is:
    Code: http://pastebin.com/6gbQJPEH
    could you tell me what is wrong here

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

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

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

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

    • 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!

        • 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!

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

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

        • 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

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

  13. 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 :)

  14. Hi Mayank, as u suggested, -so I was able to STOP timer1 from the main(), by writing TCCR1B=0×00;, ..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.

We'd love to hear from you!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s