Ok, ich werde es heute mal mit Ganzzahlwerten machen, und die anderensignalform testen.

Ich messe mitneinemn Oszi

EDIT:

Die anderen Signalformen gehen auch nicht.

Ich hab mal die ganze Berechnung in die Main-Funktion rein getan, damit die Inerruptroutine schneller ist:

Code:
#include <avr\io.h>
#include <avr\interrupt.h>
#include <math.h>


#define F_CPU 8000000

#define   interruptsProSekunde (F_CPU/256)
#define   periodendauer (1/frequenz)
#define   interruptsProPeriode (periodendauer/interruptsProSekunde)

#define round(x)    ((unsigned) ((x) + .5))




//######################################################################################################
//Variablendeklaration
//######################################################################################################


volatile uint16_t frequenz;      //frequenz in Hz
volatile uint8_t signalform;      //gewünschte signalform 0=sinus, 1=dreieck, 2=sägezahn, 3=rechteck

uint8_t ausgang;                  //Ausgangsport
uint16_t x;



//######################################################################################################
//Timer-Initialisierung
//######################################################################################################


void init(void)
{
	TIMSK=(1<<TOV0);               //Timer Overflow Interrupt einschalten
	TCNT0=0x00;                     //Zähler-Startwert setzen
	TCCR0=(1<<CS00);               //vorteiler: 1
	sei();                        //Interrupts einschalten
}



//######################################################################################################
//Interrupt-Routine
//######################################################################################################


ISR(TIMER0_OVF_vect)               //Interrupt-Routine
{
	if(x<interruptsProPeriode)
   	{
      	x++;                        //x nimmt werte von 0-interruptsproperiode an
   	}
   	else							//Periode zu Ende
   	{
   	   	x=0;						//von vorne beginnen
   	}


   if(PORTB==0b00000001)			//zum testen
   {
      PORTB=0b00000000;
   }
   else
   {
      PORTB=0b00000001;
   }
}



//######################################################################################################
//Main-Funktion
//######################################################################################################


int main(void)
{
   DDRD=0b11111111;
   DDRB=0b11111111;
   init();

   while (1)
   {
      frequenz=1000;
      //frequenz einstellen
      signalform=3;
      //signalform einstellen


		switch(signalform)
		{
       		case 0:                        //signalform=sinus
      	  		ausgang=round((sin(x/interruptsProPeriode*2*M_PI))*255);             //spannungsberechnung für sinus-signal mit sinus funktion
        	break;

      		case 1:                        //signalform=dreieck
          		if((0<=(x/interruptsProPeriode))&((x/interruptsProPeriode)<=0.25))
            	{
               		ausgang=round((x/interruptsProPeriode*2+0.5)*255);            //spannungsberechnung für dreieck-signal mit dreieck funktion
            	}

            	if((0.25<(x/interruptsProPeriode)) &((x/interruptsProPeriode)<0.75))
            	{
               		ausgang=round((1-(x/interruptsProPeriode-0.25)*2)*255);
            	}

            	if((0.75<=(x/interruptsProPeriode))&((x/interruptsProPeriode)<=1))
            	{
            	    ausgang=round(((x/interruptsProPeriode-0.75)*2)*255);
           	 	}
        	break;

       		case 2:                        //signalform=sägezahn
          		ausgang=round(x/interruptsProPeriode*255);                     //spannungsberechnung für sägezahn-signal mit sägezahn funktion
        	break;

       		case 3:                        //signalform=rechteck
          		if((x/interruptsProPeriode)<0.5)                  //spannungsberechnung für rechteck-signal mit rechteck funktion
            	{
               		ausgang=0;
            	}
            	else
            	{
               		ausgang=255;
            	}
            	//verstellbarer dutycycle wäre praktisch
        	break;
   		}


   		PORTD=ausgang;                  //gerundeten wert auf port D (r2r-netzwerk angeschlossen) legen
   }

}
Und genügt es, wenn ich jetzt keine double sondern nur noch uint8_t und uint16_t habe, oder dürfen in den Zwischenschritten der Berechnungen auch nur Ganzzahlen raus kommen?