Timer 1 & 2 VS ISR

Hi,

I am testing the timers 1 and 2 on an arduino UNO with ISR.

I connected a probe of my oscilloscope to the PIN A5, and the PIN A5 is toggled if the ISR is "slow" to be executed.

Firstly I tested timer 1 in FAST PWM mode and prescaler at 1.

void setup() {

 // Configuration of Pin connected to oscilloscope
  DDRC  |= B00100000; // set pin A5 as digital output
  PORTC &= B11011111; // set pin A5 low

// configuration of Timer 1
  TCCR1A = 0x03; // PWM Fast mode selected
  TCCR1B = 0x01; // No prescaler --> 16Mhz
  OCR1A  = 200;   // Set OCR1A at 200
  TIMSK1 = 0x02;  // interrupt on compare match with OCR1A, so when TCNT1 = 200 we enter in ISR

  
}

void loop() {
  // put your main code here, to run repeatedly:

}

ISR (TIMER1_COMPA_vect) {

  // Normaly we should not enter in this statement because ISR should be run when TCNT1 >= 200
  if (TCNT1 > 0 && TCNT1 <200)
  {
    // toggle of A5 pin
    PORTC |= B00100000;
    PORTC &= B11011111;
  }
  TIFR1 |= B00000010; // clear interrupt flag
}

The result of PIN A5 to the oscilloscope is in the attached file (see Test_Timer_1)

And I did the same test with Timer 2

Here is the code

void setup() {

 // Configuration of Pin connected to oscilloscope
  DDRC  |= B00100000; // set pin A5 as digital output
  PORTC &= B11011111; // set pin A5 low

// configuration of Timer 2
  TCCR2A = 0x03; // PWM Fast mode selected
  TCCR2B = 0x01; // No prescaler --> 16Mhz
  OCR2A  = 200;   // Set OCR2A at 200
  TIMSK2 = 0x02;  // interrupt on compare match with OCR2A, so when TCNT2 = 200 we enter in ISR

  
}

void loop() {
  // put your main code here, to run repeatedly:

}

ISR (TIMER2_COMPA_vect) {

  // Normaly we should not enter in this statement because ISR should be run when TCNT2 >= 200
  if (TCNT2 > 0 && TCNT2 <200)
  {
    // toggle of A5 pin
    PORTC |= B00100000;
    PORTC &= B11011111;
  }
  TIFR2 |= B00000010; // clear interrupt flag
}

And the result of pin A5 with the oscilloscope (see Test_Timer_2) is in the attached file

Because of no Prescaler was selected, we need 16us to count from 0 to 255.

For Timer 1 we can see a spike every 160 us
For Timer 2 we can see a spike every 1 ms

So it means that periodicaly, the "if statement" in the ISR needs more than 50 clock cycles to be executed.

Is there any reason for this ? And why is it different for Timer 1 and 2 ?

Thanks for your help !

Xavier

If you want CTC use:
TCCR1A = 0x02; // CTC

EDIT
TCCR1A = 0x00; //
TCCR1B = 0x09; //

Timer1 and Timer2 don't share WGM values. 0x03 is "Fast PWM 8-bit" on Timer2 but "PWM, Phase Correct, 10-bit" on Timer1.

Try these changes:

TIMER1

void setup()
{
  // Configuration of Pin connected to oscilloscope
  DDRC  |= B00100000; // set pin A5 as digital output
  PORTC &= B11011111; // set pin A5 low

  // configuration of Timer 1
  TCCR1A = 0x00; // 
  TCCR1B = 0x09; // 
  OCR1A  = 200;  // Set OCR1A at 200
  TIMSK1 = 0x02; // interrupt on compare match with OCR1A, so when TCNT1 = 200 we enter in ISR

}


void loop()
{
  // put your main code here, to run repeatedly:

}

ISR (TIMER1_COMPA_vect)
{
  // Normaly we should not enter in this statement because ISR should be run when TCNT1 >= 200
  if (TCNT1 > 0 && TCNT1 < 200)
  {
    // toggle of A5 pin
    PORTC |= B00100000;
    PORTC &= B11011111;
  }
  TIFR1 |= B00000010; // clear interrupt flag

}

TIMER2

void setup()
{
  // Configuration of Pin connected to oscilloscope
  DDRC  |= B00100000; // set pin A5 as digital output
  PORTC &= B11011111; // set pin A5 low

  // configuration of Timer 2
  TCCR2A = 0x02; // 
  TCCR2B = 0x01; // No prescaler --> 16Mhz
  OCR2A  = 200;  // Set OCR2A at 200
  TIMSK2 = 0x02; // interrupt on compare match with OCR2A, so when TCNT2 = 200 we enter in ISR

}


void loop()
{
  // put your main code here, to run repeatedly:

}

ISR (TIMER2_COMPA_vect)
{
  // Normaly we should not enter in this statement because ISR should be run when TCNT2 >= 200
  if (TCNT2 > 0 && TCNT2 < 200)
  {
    // toggle of A5 pin
    PORTC |= B00100000;
    PORTC &= B11011111;
  }
  TIFR2 |= B00000010; // clear interrupt flag
}

Thanks ! My mistake !
So I tested again by configuring correctly timer 1 in PWM FAST MODE and now I have the same thing for timer 1 and 2.

Every 1ms I am able to enter in the "if statement" in the ISR. So it means that sometimes it need more 50 clock cycles to reach the if statement after the interrupt.

But I don't know why because I am not doing anything else ! Any thought ?

Thanks,

Xavier

Try sketchs in post #5.

Hi LarryD

I don't want to use CTC mode but PWM FAST MODE 8 bit.

My goal is to not enter in the if statement in the ISR.

Because OCR1A is set at 200. I thought that it was enough time to run completely the ISR function. But as you can see in my previous tests, sometimes TCNT1 has already been cleared and is between 0 and 200. And I don't know why because I don't do anything in this code.

Xavier

Did you disable the Timer0 overflow interrupt?

Thanks !!! You are a master !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.