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:
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?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 } }







Zitieren

Lesezeichen