Hi!

Danke für die schnellen Antworten!

Ich habe mal alle eure Tipps befolgt, bis auf das ohne Sinus, das mach ich morgen, und jetzt sieht der Code so aus:

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))

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
double spg=0;                     //Berechneter Spannungswert des Ausganges
uint16_t x;
double x2;
double x3;


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


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

	x2=x/interruptsProPeriode*2*M_PI;   //x2 nimmt werte von 0-2Pi an
	x3=x/interruptsProPeriode;            //x3 nimmt werte von 0-1 an

	switch(signalform)
	{
	 	case 0:               			//signalform=sinus
    		spg=sin(x2);               		//spannungsberechnung für sinus-signal mit sinus funktion
   		break;

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

      		if((0.25<x3) &(x3<0.75))
      		{
      		   spg=1-(x3-0.25)*2;
      		}

      		if((0.75<=x3)&(x3<=1))
      		{
       			spg=(x3-0.75)*2;
      		}
   		break;

	 	case 2:               			//signalform=sägezahn
    		spg=x3;                     //spannungsberechnung für sägezahn-signal mit sägezahn funktion
   		break;

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



   spg=spg*255;                  //vorher spg: 0-1, nacher spg: 0-255
   ausgang=round(spg);            //runden
   PORTD=ausgang;                  //gerundeten wert auf port D (r2r-netzwerk angeschlossen) legen


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


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

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

}
Die LED an PB0 Blinkt mit einer Periodendauer von 1,3ms, das entspricht 770Hz, also viel zu langsam. wahrscheinlich dauert die Interruptroutine zu lange. Was passiert eigentlich, wenn während der Ausführung der Interruptroutine ein Interrupt ausgelöst wird? Bricht sie dann ab und Beginnt von vorne, oder macht sie einfach weiter?

EDIT: was ich noch vergessen habe: PD0 und PD1 sind jetzt dauerHigh, der restliche PortD ist Low