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?
Lesezeichen