Ihr hattet recht. Der Fehler lag an der falschen Berechnung der Zeitdifferens.
So ist es richtig.
Code:
 
	if(counter_neu > counter_alt){
		time_delta = counter_neu - counter_alt;}	// ermittel die Zeitdifferenz
	else{
		time_delta = (65535-counter_alt) + counter_neu;}	// ermittel die Zeitdifferenz
Damit andere auch etwas davon haben hier der gesammte Code für einen Mega16. Ich verwende das ATmega16 Testboard v2.0 von kreatives-chaos.com
main.c
Code:
/**        
* Mit hilfe dieses Programmes soll die Drehzal 
* über ein UART interfase am PC ansgegeben werden.
* Dazu wird die Drehzal wie folgt ermittelt:
*
* Zeit(Timer0) zwischen zwei Impulsen
* 
* 
* Hierzu wird bei einen Externen Interrupt(INT0), 
* die bisher vergangene Zeit des Timers0 über UART ausgegeben
*
**/

#include <avr/interrupt.h>
#include <stdint.h> // integerwerte wie uint8_t, uint16_t
#include <stdlib.h> // itoa
#include "timer0.h"	// einbinden der Header datei für Timer0
#include "uart.h"	// einbinden der Header datei für UART
//nicht vergessen die Passenden C Dateien in der Makefile zu schreiben

#define STATUS_LED1 PB3		// PIN der on-board Status-Led
#define STATUS_LED2 PB2		// Pin der on-board Status_Led


void init(void);			// allgemeine Initialisierung
void auswerten(void);		// Status Ausgabe über UART

volatile uint16_t counter_alt;		// alter Timerstand
volatile uint16_t counter_neu;		// neuer Timerstand
volatile uint16_t time_delta;		// Zeitdifferens

volatile uint16_t m1,m2,m3,m4,m5,m6,m7,m8,m9,m0; //Mittelwertbildung
volatile uint8_t sm;

int main(void){	
	
	init();			// Allgemeine Port initialisierung
	timer0_init();	// Timer0 initialisieren
	uart_init();	// UART initialisieren
	
	sei();	//global Interrupts Aktivieren
	
	uart_putc('*');			//senden eines einzelenen Zeichen
	uart_puts(" UART inizialisierung ... OK \n\r\n\r");	//sendet einen string
/*uart_puts("* Drehzahl1\r\n* Mit hilfe dieses Programmes soll die Drehzal \r\n");
uart_puts("* ueber ein UART interfase am PC ansgegeben werden.\r\n* Hierfuer wird die Drehzal wie folgt ermittelt. \r\n");
uart_puts("* Zeit(Timer0) zwischen zwei Impulsen\r\n");
uart_puts("* Hierzu wird alle durch einen Externen Interrupt(INT0) \r\n");
uart_puts("* Die Bisher vergangene Zeit des Timers0 über UART ausgegeben\r\n");
*/

	while(1)
	{	}
	//never reached   i hope ;)
}


void init(void)
{
	/* STATUS_LED1 und 2 als Ausgang  */
	DDRB |= (1 << STATUS_LED1) | (1 << STATUS_LED2);
	PORTB &= ~((1 << STATUS_LED1) | (1 << STATUS_LED2));

	/* INT0 init */	
	DDRD &= ~(1<<PD2);		//PORTD.2 als Eingang
	PORTD |= (1<<PD2);		//PORTD.2 mit Pullup
	GICR |= (1<<INT0);		// External Interrupt Request 0 Enable
	MCUCR |= (1<<ISC01)|(1<<ISC01);	// Die steigende Flanke an INT0 erzeugt einen Interrupt. 
	
	/* globale Variablen vorbelegen */
	counter_alt = 0; 		
	counter_neu = 0;
	m1=m2=m3=m4=m5=m6=m7=m8=m9=m0=0;
}

void auswerten(void)
{
	/* gibt Zählerstand über UART aus */
	unsigned char s[7]; 		// max -65536 entspricht 7 Zeichen
	
	uart_puts("Drehzahl: ");	// Textausgabe
	utoa(time_delta, s, 10);	// Uint_16 in Asci-String wandeln
	uart_puts(s);				// Textausgabe 
	uart_puts("      \r");		// Textausgabe
}


// Interrupt Service Routine bei Flanke an int0(extern) */
ISR(INT0_vect)
{
	PORTB ^=(1<<PB2);								// Toggel Led, wildes blinken ist immer gut
	counter_neu = (timer0_counter_D1*256) + TCNT0;	// Merke mir die Uhrzeit
	//timer0_counter_D1=0;							// sezte den Umrundungsmerker zurück
	if(counter_neu > counter_alt){
		time_delta = counter_neu - counter_alt;}	// ermittel die Zeitdifferenz
	else{
		time_delta = (65535-counter_alt) + counter_neu;}	// ermittel die Zeitdifferenz
	
	/* gleitender Mittelwert über 10 Messungen */	
	//m9=m8;m8=m7;m7=m6;m6=m5;m5=m4;m4=m3;m3=m2;m2=m1;m1=m0;m0=time_delta;
	//time_delta=(m1+m2+m3+m4+m5+m6+m7+m8+m9+m0)/10;	
	
	counter_alt = counter_neu;						// Merke mir die Uhrzeit für die nächste Messung
}
timer0.c
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "timer0.h"

/* Timer0 initialisieren */
void timer0_init(void)
{
	/* alle 1,48ms Überlauf.Einstellen der Frequenz auf 675Hz ( Prescaler = 64  * 256 bis Überlauf ) */
	TCCR0 |= ((1<<CS01) | (1<<CS00));// Prescaler 64, entspricht 5,8usec und 1,48ms bis überlauf
	
	/* Interrupts für Timer0 aktivieren */	
	TIMSK |= (1<<TOIE0);
	
	DDRB |= (1<<PB3);		// toggel led
	
	timer0_counter_D1=0;		// sezte den Anfangswert
	timer0_counter=0;		// sezte den Anfangswert

}	

/* Interrupt Service Rountine bei Überlauf des Timer0 */
ISR(TIMER0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW1) */
{
    /* Interrupt Code */
	timer0_counter++;			// Merker für Überläufe des Timers
	timer0_counter_D1++;		// Merker für Überläufe des Timers, für die Drehzahl1
	
	if(timer0_counter % 30){ 	// alle 44ms 
	}else {
		auswerten();			// den Wert über UART ausgeben
	}	

	if( (timer0_counter >= 255)){	// alle 380ms 
		PORTB ^=(1<<PB3);			// eine LED getoggelt
	}
	
}