Attiny24 Timer0 setting up

Hi,

I'm trying to call a timer interrupt with Attiny 24. I've gone through the documentation, done the work; the code is:

  cli();

  //TCCR0A - set 0b0000RR10 - pins disconnected, CTC mode, reset at OCRA
  TCCR0A = 0;
  TCCR0A |= (1<<WGM01); 

  //TCCR0B set to 0b00RR0101 - prescaler 1024, 
  TCCR0B = 0;
  TCCR0B |= (1<<CS02); 
  TCCR0B |= (1<<CS00);

  //initial value in counter 0, count up to 244
  TCNT0 = 0;
  OCR0A = 244;
  
  //enable interrupt on A
  TIMSK0 = 0;
  TIMSK0 |= (1<<OCIE0A); 
  sei();
  

The idea is: prescaler 1024 at 1MHz clock counts up approximately 1000 times per second; I count up to about 250 -> about 4 interrupts per second. The IRQ handler is just toggling an LED:

ISR(TIM0_COMPA) {
  time_elapsed++;
  digitalWrite(output, digitalRead(output) ^ 1);    //toggle pin ON/OFF
  }
}

The LED lights up once and then stays on. What am I doing wrong with the setup? Is there a register I forgot? Should I use Timer1 instead, or something like that?

Thank you!

I suggest you post your complete code, so people can test it.

Hi,

thanks for the prompt. A full code that doesn't work is below; all setup I have is an LED on pin 10. In the setup, its blinks once and then stays on even though the interrupts should turn it off. Once I have this I can start changing the ISR to actually do something meaningful but as of now, I don't really know if the interrupt is triggered or not.

int output = 10;

ISR(TIMER0_COMPA_vect) {
  digitalWrite(output, digitalRead(output) ^ 1);    //toggle pin ON/OFF
  }
}

void setup() {

  //test connection - LED at pin 10 should blink once ON-OFF
  pinMode(output,OUTPUT);

  digitalWrite(output,HIGH);
  delay(1000);
  digitalWrite(output, digitalRead(output) ^ 1);
  delay(1000);

  //setup the timer 1
  cli();

  //TCCR0A - set 0b0000RR10
  TCCR0A = 0;
  TCCR0A |= (1<<WGM01); 

  //TCCR0B set to 0b00RR0101
  TCCR0B = 0;
  TCCR0B |= (1<<CS02); 
  TCCR0B |= (1<<CS00);
  TCNT0 = 0;
  OCR0A = 244;
  
  //enable interrupt on A
  TIMSK0 = 0;
  TIMSK0 |= (1<<OCIE0A); 
  sei();
  

}

void loop() {
  
}

Was something missing in the top section of the code?
It looks like you have one closing bracket too many
i removed the one just above
void setup() {

I have no AT24 to test (only AT85).
Just a shot: what happens if you change:

int output = 10;

to

volatile int output = 10;

I've modified the ISR without testing it, hence the missing bracket; before I had a simple if-else counter there.

The volatile doesn't seem to work; it just turns the LED on once and then doesn't do the toggling, hence why I think it doesn't call the interrupt correctly repeatedly but only once.

Maybe the settings it wrong and it has too long/too short period? Is it possible that after it's called once some flags are reset that disable further calls?

I've overcome the issue; instead of using a timer, I resorted back to millis() function, with rollover handling per https://www.baldengineer.com/arduino-how-do-you-reset-millis.html

I still don't understand why the timer doesn't work but my problem with determining the timings of things in the system was thus resolved. In case anyone else encounters a similar issue, feel free to use this alternative.

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