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:
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?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 } }
EDIT: was ich noch vergessen habe: PD0 und PD1 sind jetzt dauerHigh, der restliche PortD ist Low







Zitieren

Lesezeichen