Hallo
Nur keine Panik! In der Hex-Datei ist jedes Byte des Programms mit zwei Zeichen hexdezimal codiert, zusätzlich noch die Zieladressen und die Checksummen. Du kannst sie mal im Editor öffnen. Die ersten 8 Zeichen pro Zeile sind die Zieladresse im Speicher des Mega8, dann kommen 16 Bytes Daten und ein Byte Checksumme, jeweils als Hex-Wert.
Wenn ich dein Progamm kompiliere, komme ich auf 2226 Bytes Programmlänge, die Hex-Datei wird mit 7kb angezeigt. Meine Optimierung ist auf "Size" eingestellt.
Ich habe dein Programm nicht genauer untersucht, denn es scheint mir auf den ersten Blick etwas kompliziert. Möglicherweise bringt dies eine Funktion:
volatile uint16_t frequenz; //frequenz in Hz
volatile uint8_t signalform; //gewünschte signalform 0=sinus, 1=dreieck, 2=sägezahn, 3=rechteck
volatile zwingt den Kompilier, für die Variable einen Speicherplatz anzulegen. Dadurch können sowohl das Hauptprogramm wie auch die ISR auf den Wert der Variable zugreifen. (Nicht wissenschaftlich und von mir nur nachgeplappert;) Mit dieser Änderung sieht dein Programm dann so aus:
Allerdings, so aus dem Bauchgefühl heraus, könnte mindestens bei Kurvenform 1 ein Überlauf der ISR auftreten.Code:#include <avr\io.h> #include <avr\interrupt.h> #include <math.h> #define F_CPU 8000000 #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 uint16_t interruptspersecond; //anzahl der interrupts pro sekunde uint8_t ausgang; //Ausgangsport float periodendauer; //in S uint16_t interruptsproperiode; //anzahl der interrupts pro periode 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 { interruptspersecond = F_CPU/256; periodendauer=1/frequenz; interruptsproperiode=periodendauer/interruptspersecond; 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 if(signalform==0) //signalform=sinus { spg=sin(x2); //spannungsberechnung für sinus-signal mit sinus funktion } if(signalform==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; } } if(signalform==2) //signalform=sägezahn { spg=x3; //spannungsberechnung für sägezahn-signal mit sägezahn funktion } if(signalform==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 } 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 } int main(void) { DDRD=0b11111111; init(); while (1) { frequenz=1000; //frequenz einstellen signalform=0; //signalform einstellen } }
Gruß
mic






Zitieren


Lesezeichen