Timer2 is not properly working

Hi,

I tried to blink an led for every 2 seconds like below sequence.
led on - 2 seconds - led off - 2 seconds - led on......

I wanted to do it with timer2. i gave the setting for 10ms timer and counted it to 200 in ISR to get 2 seconds.But i did not able to achieve it..
Unknowingly if i count it to 2000 then blink works but the timing is not i expected.
Its as...led on - 500ms(approx) - led off - 500ms(approx) - led on - 500ms(approx) - led off.....
The code is below... Please correct me where i am wrong. I am using arduino uno running with atmega328p in 16MHz clock.

boolean attempt = 0;
const byte LED = 13;
unsigned long Timer2_Interval = 200, Timer2_Count = 0;

ISR (TIMER2_COMPA_vect) 
{
  TIFR2 = 0;
  Timer2_Count++;
  if( Timer2_Count >= Timer2_Interval )
  {
    Timer2_Count = 0;
    
    if( attempt == 1 )
    {
      attempt = 0;
      digitalWrite( LED , LOW );
    }
    else
    {
      attempt = 1;
      digitalWrite( LED , HIGH );
    }
  }
  return;
}

void setup()
{
  pinMode ( LED, OUTPUT );
  
  bitClear( PRR, 6 );
  OCR2A   = 156;
  bitSet( GTCCR, 1 );
  TCCR2A  = 0x02;      // CTC mode
  TIMSK2  = 0x02;
  TCNT2   = 0;
  TCCR2B =  0x07 ;  // prescalar = 1024
  
  sei();
}

void loop()
{
  
}

I will put money on it working properly, although it might not be working as expected.

@JimboZA:

I dont able to follow what you are saying.. Could you please elaborate little further

Murugesh:
Hi,

I tried to blink an led for every 2 seconds like below sequence.
led on - 2 seconds - led off - 2 seconds - led on......

I wanted to do it with timer2.

Wouldn't it be much much easier to do it using millis() and the Blink Without Delay technique.

If you just want to learn how to use Timer2 it would help you (most importantly) and us if you put a comment explaining each line of the Timer setup code. Sorry, but I am not going to delve into the Atmega datasheet to try to figure out your code.

It would also be a big help if you provide a description of how you are planning to use the Timer with reference to the datasheet. That way we will be able to see if you are misunderstanding something.

...R

Murugesh:
@JimboZA:

I dont able to follow what you are saying.. Could you please elaborate little further

I mean it's probably working the way it is supposed to (that is, properly), but you expect it to work differently and it's not doing that.

Well the first thing to point out is that variables accessed in an ISR and also in the
main loop code should be declared "volatile" so the compiler doesn't cache them
in registers.

Also when changing counter modes the most reliable way is set both TCCR2A and
TCCR2B to zero first to fully cancel the existing mode, then set the TCNT and OCR2A
registers, then set up the new mode by writing TCCR2A and 2B.

In particular setting the bottom 3 bits of TCCR2B to zero will stop the timer from
counting entirely, a wise precaution before changing mode.

Having said that I've no reason to doubt your setup code works, its just a possible
pitfall in some obscure situations.

OCR2A should be set to 155, not 156, since the counter period = TOP+1

Why are you switching timer2 off?

  bitClear( PRR, 6 );

Why do this?

  bitSet( GTCCR, 1 );

It resets the prescaler for timers 0 and 1, not timer2. You don't need to mess
with prscaler reset unless you are attempting to synchronize timers.

Timer2 is 8 bit timer

Why are you switching timer2 off?
Code:

bitClear( PRR, 6 );

I did it because the below information in the page no:144 of atmega328p datasheet.
"The PRTIM2 bit in ”Minimizing Power Consumption” on page 42 must be written to zero to
enable Timer/Counter2 module."

MarkT:
Also when changing counter modes the most reliable way is set both TCCR2A and
TCCR2B to zero first to fully cancel the existing mode, then set the TCNT and OCR2A
registers, then set up the new mode by writing TCCR2A and 2B.

Thanks MarkT.. Its working after i did the above mentioned thing by you