How to check for Timer1 overflow in loop()

Hey all, I’m having an issue and I can’t seem to figure out why this doesn’t work. I’d like to hold execution of the loop until a timer overflow has occurred. I used to have all my code in the ISR, but I think it was adversely effecting Serial communication.

Here is a barebones version of the code i’m trying to use:

void setup() {
   // initialize Timer1
  TCCR1B = 0x00;        //Disable Timer1 while we set it up
  TCNT1  = 0;         //Reset Timer Count to 0
  TIFR1  = 0x00;        //Timer1 INT Flag Reg: Clear Timer Overflow Flag
  TIMSK1 = (1 << TOIE1);        //Timer1 INT Reg: Timer2 Overflow Interrupt Enable
  TCCR1A = 0x00;        //Timer1 Control Reg A: Normal port operation, Wave Gen Mode normal
  TCCR1B |= (1 << CS11);       //8 prescale
}

//overflow function for timer1
ISR(TIMER1_OVF_vect) {     
   //do nothing
}

void loop() {
  while(!TIFR1);
  //overflow has occurred!
  TIFR1 = 0x00; //Clear Timer Overflow Flag
  TCNT1  = 0; //Reset Timer to 0

The loop() seems to run at full speed, unaffected by the “while(!TIFR1);” statement. Can anyone shed some light as to why?

Thanks!

How are you measuring the speed at which loop() repeats ? How long do you expect it to wait in the while() ?
You mention “all of my code” but have not posted it.

  TCCR1B |= (1 << CS11);       //8 prescale

So you are hoping that the loop will happen to reach the statement that tests TIFR1 to be zero, at exactly the point when it is? Since most instructions take between 1 and 3 clock cycles, I don’t think so.

TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location.

Since you have ISR, even it's empty, it's should clear TOV. I would use a variable (volatile) as a flag, and set it inside ISR. Than in main loop you jast test status with if / else, and if it set, you execute some code and clear variable at the end.

Try this instead:

while(!(TIFR1 & TOV1));

There are other flags in the TIFR1 register that are being set as well. You need to mask them out. You also need to disable the ISR since it will clear the TOV1 flag before you get a chance to. Or you could just set a global volatile flag in the ISR that you check at main level.

UKHeliBob: How are you measuring the speed at which loop() repeats ? How long do you expect it to wait in the while() ? You mention "all of my code" but have not posted it.

I would post it, but it would only muddle the source of my problems. The code I have posted doesn't work as desired. We'll start there.

It should be waiting around 32.8 ms. It does not. I am reporting loop times via a serial println. I didn't figure posting those debug statements would be helpful.

No… I am waiting for it in a while statement.

decathect: It should be waiting around 32.8 ms. It does not. I am reporting loop times via a serial println. I didn't figure posting those debug statements would be helpful.

If the prescaler is 8 and the clock is 16MHz, then the 16 bit timer will overflow every 65536 / 8000000 = 8.192mS. How about the other suggestion I gave you about disabling the ISR or setting a global flag?

EDIT: OOps, I see what I did wrong. You are right on the overflow time, sorry about that. Still you need to look at my other post's suggestions.

65536 / 2000000= 32.768mS

afremont:
Try this instead:

while(!(TIFR1 & TOV1));

There are other flags in the TIFR1 register that are being set as well. You need to mask them out. You also need to disable the ISR since it will clear the TOV1 flag before you get a chance to. Or you could just set a global volatile flag in the ISR that you check at main level.

Thanks, that worked. I had tried using a flag variable, but the ‘volatile’ keyword is what I was missing.