TIMER1 Good, Timer0 Bad

I thought that the following code would give me change in pin 8's state at about 125KHz.

I think it's setting the overflow interrupt on Timer0.

bool state = HIGH;

void setup() {
  pinMode(8, OUTPUT);

  noInterrupts();
  TCCR0A = 0;

  TCCR0B = 0;
  TCCR0B |= (1 << CS02);
  
  TIFR0 |= (1 << TOV0);
  TIMSK0 |= (1 << TOIE0);
  interrupts();
}

void loop() { ; }

ISR(Timer0_OVF_vect) {
  static bool state = LOW;
  digitalWrite(8, state);
  state = !state;
}

I don't get any signal (other that some noise). An identical sketch working on Timer1 runs as expected:

bool state = HIGH;

void setup() {
  pinMode(8, OUTPUT);

  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;

  TCCR1B |= (1 << CS10);

  TIFR1 |= (1 << TOV1);
  TIMSK1 |= (1 << TOIE1);
  interrupts();
}

void loop() { ; }

ISR(TIMER1_OVF_vect) {
  static bool state = LOW;
  digitalWrite(8, state);
  state = !state;
}

I thought it could be that the TIMERx_OVF_vect casing might be the cause, the camel-case form of TIMER1 compiles but doesn't produce an output either, however the uppercase version of Timer1 causes a compilation error.

Timer0 is used to keep millis() going.

Can you use the output of the hardware timer for the 125kHz, or do you need the interrupt for other things ?

I know that, I thought that if I didn't care about millis(), delay() etc. then I could still use it.

I'm not actually changing it at all here, just trying to hook into the overflow interrupt.

I'm just playing with it, trying to learn what's what.

Even if you don't need millis() function, you can't use TIMER0_OVF_vect because the Arduino Core has defined a Timer0 overflow interrupt (a.k.a. TIMER0_OVF_vect).

If you write multiple ISRs of the same vector, a compile error will occur.

Try using TIMER0_COMPA_vect instead of TIMER0_OVF_vect.
The overflow interrupt must be released and the compare match A interrupt must be enabled.

I think that you do not learn by messing around with the Arduino basics. Use Timer1 and Timer2. Learn, for example, about all the different PWM modes, that will keep you busy for a while.

Timer0 is also used by analogWrite() when a PWM pin is selected that is a output of Timer0.

That makes sense. Thanks.

I think that should have been spelled
ISR(TIMER0_OVF_vect) {

Then you will get the compilation error that interrupt vector 16 is already defined.

1 Like

Without all the Arduino stuff pulled in, it can work

bool state = HIGH;

int main(void) {
  pinMode(8, OUTPUT);

  noInterrupts();
  TCCR0A = 0;

  TCCR0B = 0;
  TCCR0B |= (1 << CS02);
  
  TIFR0 |= (1 << TOV0);
  TIMSK0 |= (1 << TOIE0);
  interrupts();
  while(1){};
}


ISR(TIMER0_OVF_vect) {
  static bool state = LOW;
  digitalWrite(8, state);
  state = !state;
}

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