Hi Stefan,

vielen Dank für Deinen Hinweis! Ich habe nun zwei Varianten getestet, um das beschriebene Problem zu verhindern.

1. Möglichkeit: Ich lösche das Timer0 Overflow Flag manuell, indem ich eine 1 ins TOV0 schreibe. Das funzt wunderbar! Hier der Code zur Dokumentation:

Code:
/ 
#define F_CPU 16000000UL

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



void InitTimer0()
{
    //TCCR0 |= (1<<WGM01) | (1<<WGM00);                //Fast PWM
    TCCR0 |= (1<<CS01) | (1<<CS00) | (1<<COM00)    ;    //Setup timer0 in normal mode with a prescaler of 64; enable OVF interrupt in main loop to start interrupt generation
    DDRB |= (1<<PB3);                                //set OC0 as output
    //TIMSK |= (1<<TOIE0);                            //enable timer0 OVF interrupt;
}

void StopTimer0()
{
    TCCR0 &= ~(1<<COM00);                //Set pin mode to normal operation; if this is not done, the pin will stay at the last logical level when stoppting timer
    TCCR0 &= ~(1<<CS02);                //Stops timer according to datasheet
    TIMSK &= ~(1<<TOIE0);                //disable timer0 OVF interrupt;
}


int main (void)
{  
   MCUCR |= (1<<ISC00);        //interrupt on any logical change on Int0 "PD2"
   GICR |= (1<<INT0);        //enable INT0 interrupt
   DDRA |= (1<<PA1);        //Pin PA1 as output
   
   InitTimer0();            //start timer 0
   
   sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
   
      
   while(1)                    
   {    
        //nothing here except interrupts    
    }
          
}



ISR(INT0_vect)                        //ISR when logical change on INT0 "PD2"
    {    
        
        GICR &= ~(1<<INT0);            //disable this IRF; enable again when the timer0 OVF ISR fires
        TIFR |= (1<<TOV0);            //clear Timer 0 Overflow flag by writing one to the register!
        TIMSK |= (1<<TOIE0);        //enable timer0 OVF interrupt; will fire about 1ms after this ISR has completed
        TCNT0 = 250;                    //Write x to timer 0 to restart counting; any 8 bits work to adjust delay
        PORTA |= (1<<PA1);            //Set PA1 high when INT0 fires
        //SFIOR |= (1<<PSR10);        //Reset prescaler
    }

ISR(TIMER0_OVF_vect)
    {    
        TIMSK &= ~(1<<TOIE0);        //disable timer0 OVF interrupt -> enable again in next INTO ISR
        //StopTimer0();                //Stop timer0
        GICR |= (1<<INT0);            //turn on INT0 IRF again                                            
        PORTA &= ~(1<<PA1);            //Set PA1 low again when Timer0 OVF ISR fires -> High pulse after logic level change on INT0 pin
    }
Mit diesem Code läuft der Timer0 durchgehend. Ich habe mal das Delay zwischen Eintreffen des externen Interrupts und dem Hochziehen von PA1 mitm Oszi gemessen. Das Delay beträgt ca. 2µs. Siehe Bild:

Klicke auf die Grafik für eine größere Ansicht

Name:	NewFile22.jpg
Hits:	3
Größe:	48,6 KB
ID:	22199

Falls man den Timer0 für andere Sachen benötigt, während der externe Interrupt abgearbeitet ist, kann man Folgendes machen...

2. Möglichkeit: Ich starte und stoppe den Timer, indem ich den Prescaler an- bzw. ausschalte (siehe Datenblatt). Um das Timer Overflow Flag und das entsprechende Enable Bit braucht man sich nicht mehr zu kümmern. Hier der Code zur Dokumentation:

Code:
#define F_CPU 16000000UL

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


/*
void InitTimer0()
{
    //TCCR0 |= (1<<WGM01) | (1<<WGM00);                //Fast PWM
    TCCR0 |= (1<<CS01) | (1<<CS00) | (1<<COM00)    ;    //Setup timer0 in normal mode with a prescaler of 64; enable OVF interrupt in main loop to start interrupt generation
    DDRB |= (1<<PB3);                                //set OC0 as output
    //TIMSK |= (1<<TOIE0);                            //enable timer0 OVF interrupt;
}

void StopTimer0()
{
    TCCR0 &= ~(1<<COM00);                //Set pin mode to normal operation; if this is not done, the pin will stay at the last logical level when stopping timer
    TCCR0 &= ~(1<<CS01) | ~(1<<CS00);    //Stops timer according to data sheet
    TIMSK &= ~(1<<TOIE0);                //disable timer0 OVF interrupt;
}
*/

int main (void)
{  
   MCUCR |= (1<<ISC00);        //interrupt on any logical change on Int0 "PD2"
   GICR |= (1<<INT0);        //enable INT0 interrupt
   DDRA |= (1<<PA1);        //Pin PA1 as output
   
   /*This will init timer0 without starting it*/
   DDRB |= (1<<PB3);        //set OC0 as output
   TCCR0 |= (1<<COM00);        //Setup timer0 in normal mode
   TIMSK |= (1<<TOIE0);        //enable timer0 OVF interrupt;
   
   sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
   
      
   while(1)                    
   {    
        //nothing here except interrupts    
    }
          
}



ISR(INT0_vect)                                //ISR when logical change on INT0 "PD2"
    {    
        
        GICR &= ~(1<<INT0);                    //disable this IRF; enable again when the timer0 OVF ISR fires
        TCCR0 |= (1<<CS01) | (1<<CS00);        //start Timer0 by setting prescaler (here 64)!
        TCNT0 = 250;                        //Write x to timer 0 to restart counting; any 8 bits work to adjust delay
        PORTA |= (1<<PA1);                    //Set PA1 high when INT0 fires
    }

ISR(TIMER0_OVF_vect)
    {    
        TCCR0 &= ~(1<<CS01) | ~(1<<CS00);    //Stops timer according to data sheet (unset prescaler)
        GICR |= (1<<INT0);                    //turn on INT0 IRF again                                            
        PORTA &= ~(1<<PA1);                    //Set PA1 low again when Timer0 OVF ISR fires -> High pulse after logic level change on INT0 pin
    }
Am Oszi schaut das dann so aus:

Klicke auf die Grafik für eine größere Ansicht

Name:	NewFile33.jpg
Hits:	3
Größe:	44,3 KB
ID:	22200

Es ist zu erkennen, dass der Interrupt schneller verarbeitet wird als bei Möglichkeit 1 (ca. 200ns schneller). Das ist nicht viel, aber man kann den Timer nun in den Pausen für was anderes hernehmen. Ich werd's also so machen.

Vielleicht helfen diese Codeschnippsel ja jemand. Danke nochmals für die Hilfe!

Schönen Abend noch,

Christian