//TIMER4 initialize - prescale:256
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Hz
// actual value:  1.000Hz (0.0%)
void timer4_init(void)
     TCCR4B = 0x00; //stop
     TCNT4H = 0x1F; //Counter higher 8 bit value
     TCNT4L = 0x01; //Counter lower 8 bit value
     OCR4AH = 0x00; //Output Compair Register (OCR)- Not used
     OCR4AL = 0x00; //Output Compair Register (OCR)- Not used
     OCR4BH = 0x00; //Output Compair Register (OCR)- Not used
     OCR4BL = 0x00; //Output Compair Register (OCR)- Not used
     OCR4CH = 0x00; //Output Compair Register (OCR)- Not used
     OCR4CL = 0x00; //Output Compair Register (OCR)- Not used
     ICR4H  = 0x00; //Input Capture Register (ICR)- Not used
     ICR4L  = 0x00; //Input Capture Register (ICR)- Not used
     TCCR4A = 0x00; 
     TCCR4C = 0x00;
     TCCR4B = 0x04; //start Timer

I'm trying to figure how to use the Timer 4 in ATmega2560. This is the code I've found for a 1 sec timer. A timer interrupt takes places after every 1 sec. How can I use this code to achieve a 0.1 sec timer (i.e. schedule the ISR for every 0.1s)?

  • \$\begingroup\$ It would help if you added comments for each line, describing the register names (and its bits). Not just for us, for yourself just as well. Start by checking the datasheet for the register names. \$\endgroup\$ – jippie Jan 22 '16 at 18:10
  • \$\begingroup\$ @jippie Done..! \$\endgroup\$ – user87877 Jan 22 '16 at 18:15
  • \$\begingroup\$ Does the chapter on timer 4 mention any formula on TCNT? \$\endgroup\$ – jippie Jan 22 '16 at 18:18
  • \$\begingroup\$ Do you know which part of that code sets the timer interval to 1s? If not, review the datasheet. If so, you should be able to at least guess at how you might change the register values to obtain 0.1s. \$\endgroup\$ – uint128_t Jan 22 '16 at 18:19
  • 1
    \$\begingroup\$ I understand that. The datasheet will clear things up. More specifically, doing a search for "TCNT" and reading those sections will be very helpful. \$\endgroup\$ – uint128_t Jan 22 '16 at 18:32

Using a timer is easier than it sounds. It works like this:

You have a timer that is fed with a clock. The clock can be the system clock, an external source (not available on every AVR) or the system clock divided by a pre scaler. You can trigger an ISR on an overflow of the timer. The timer-register can be 8 or 16bit wide. (I am not sure if 32 bit wide timer register exist)


Using a 8 bit timer with a 1MHz timer clock will give you an overflow every 255us, meaning your ISR would be called every 255us:

enter image description here

There is also an option to adjust the trigger threshold with registers so you are able to trigger on different values than the overflow value, like 127us. There is also another way to achieve this: initialize the timer counter value to a value other than zero and wait for the overflow to happen. If the overflow occurred you reset the timer to your start position again.

Short side note: If your ISR takes longer than your ISR interval then you will miss some ISRs!

If you are going to use timers then you always have to consider the following things:

  • What frequency do I need?
  • What duty-cycle do I want? (for PWM applications)
  • What system clock am I using?
  • Do I want an ISR to be triggered or to toggle an output pin?

If you can answer all these questions then you can move forward!

The data sheet gives all answers on how to setup the timer:

You want to use timer 4 on the ATmega2560 which is 16 bits wide (source: page 158 of the complete ATmega2560 datasheet).

Then you need to calculate a fitting pre scaler for your clock and calculate a fitting timer overflow threshold value...

I know the data sheet can sometimes be misleading at first glance but give yourself a little time and you will understand it!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.