ATtiny85, delay() and TIMER0_COMPA_vect

Hi!

I use ATtiny from Google Code Archive - Long-term storage for Google Code Project Hosting. (Google Code Archive - Long-term storage for Google Code Project Hosting.) and try to implement a timer interrupt. This small test program shall blink on pin 1 with 0,5 Hz and do some higher frequent stuff on pin 0. Hardware is ATtiny85 at 8 MHz. Bootlooader burned.

It works really fine if I don't do the "setupisr();". Blinks like a charm. If I do it, all hell breaks lose on Pin 1 and 0.

/*
 "Burnbootloader" burned
 */

#include <avr/io.h>
#include <avr/interrupt.h>

const byte PinLEDgreen = 0;
const byte PinLEDblue = 1;

void setupisr() {
  cli();

  TCCR0A = 0;
  TCCR0B = 0;

  // set up Timer 0
  TCCR0B |= bit (CS00) | bit (CS02);    // Prescaler  1024
  TCCR0A |= bit (WGM01);                // Timer 0 in CTC mode
  OCR0A = 127;                          // CTC Compare value (count up to 128)
  TIMSK = (1<<OCIE0A);

  sei();
}

ISR(TIMER0_COMPA_vect)
{
  cli();
  digitalWrite(PinLEDgreen, ! digitalRead(PinLEDgreen));
  sei();
}

void setup()
{
  pinMode(PinLEDgreen, OUTPUT);
  pinMode(PinLEDblue, OUTPUT);

  setupisr();
}

void loop(){

  digitalWrite(PinLEDblue,HIGH);
  delay(1000);
  digitalWrite(PinLEDblue,LOW);
  delay(1000);
}

Anyone sees my error? Any hints? Any ideas?

(Goal is to get the OneWire lib running on ATtiny85 and have timer interrupts...)

Thanks!

ISR(TIMER0_COMPA_vect)
{
  cli();  // <<<<< Bad idea.  Remove this line.

  digitalWrite(PinLEDgreen, ! digitalRead(PinLEDgreen));

  sei();  // <<<<< Bad idea.  Remove this line.
}

Does not change anything. I removed all sei()/cli().

Without setupisr(); I get something about 0,5 Hz at Pin 1 and nothing at Pin 0

Adding setupisr(); I get about 15 Hz at Pin 1 and about 30 Hz at Pin 0.

Disabling Timer1 gives the expected 30 Hz at Pin 0 and (of course) nothing on Pin 1.

This should work, the only differense is this line:

TCCR0A |=(1<<COM0A1); //Timer0 in toggle mode Table 11.2
const byte led4 = 4;
const byte led3 = 3;

volatile int count = 0; 

void setup(){
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  cli();
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |=(1<<WGM01); //Start timer 1 in CTC mode Table 11.5
  TCCR0B |= (1 << CS02) | (1 << CS00); // Prescaler =1024 Table 11.6
  OCR0A=127; //CTC Compare value
  TCCR0A |=(1<<COM0A1); //Timer0 in toggle mode Table 11.2
  TIMSK |= (1 << OCIE0A); 
  sei();
}

ISR(TIMER0_COMPA_vect)
{
  count++;
  if (count>30){
    digitalWrite(led4, ! digitalRead(led4));
    count=0;  
  }

}

void loop(){
  digitalWrite(led3,HIGH);
  delay(1000);
  digitalWrite(led3,LOW);
  delay(1000);
}

Thanks Erni,

it really works.

Could you explain what happens? I read the PDF but I don't see the reason....

Thanks!

That was not a good example, sorry.
The below example works, it seems that the order of the commands are important.

const byte led4 = 4;
const byte led3 = 3;

volatile int count = 0; 

void setup(){
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  cli();
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |=(1<<WGM01); //Start timer 1 in CTC mode Table 11.5
  TIMSK |= (1 << OCIE0A); //Enable CTC interrupt see 13.3.6
  OCR0A=127; //CTC Compare value
  TCCR0B |= (1 << CS02) | (1 << CS00); // Prescaler =1024 Table 11.6
  sei();
}

ISR(TIMER0_COMPA_vect)
{
  count++;
  if (count>30){
    digitalWrite(led4, ! digitalRead(led4));
    count=0;  
  }

}

void loop(){
  digitalWrite(led3,HIGH);
  delay(1000);
  digitalWrite(led3,LOW);
  delay(1000);
}