Hallo :-) Ich versuche gerade mit einem atmega16 einen Sinusgenerator aufzubauen. Die Schaltung ist relativ simpel aufgebaut: - atmega16 - 16MHz Quarz - an PortB befindet sich ein 8Bit R2R DAC Den R2R DAC habe ich auf einer kleinen Lochrasterplatine aufgebaut. Der atmega16 befindet sich auf einem STK500. Die Schaltung/Software funktioniert grundsätzlich. Ich bin mir jetzt etwas unsicher was die Berechnung der Ausgangsfrequenz angeht. - Ich habe mal mein kleines Programm angehängt. Konzept des programms ist folgendes: - Timer1 zählt mit der Quarzfrequenz (CS10 = 1) - Bei OCR1A comparematch wird ein INT ausgelöst. (OCIE1A = 1) - Bei comparematch wird TCNT1 auf 0 zurückgestellt (WGM12 = 1) - Im INT wird ein Wert aus der Sinustabelle sintable[16] im PROGMEM ausgelesen und auf den DAC ausgegeben. Danach wird i um 1 hochgezählt, um beim nächsten INT den nächsten Wert aus der sintable zu holen. Nach einer Periode (16 Werte) wird i auf 0 zurückgesetzt. ... ich dachte mir mal ganz unbedarft und naiv, dass ich der OCR1A comparewert wie folgt berechnet: ;-) Quarzfrequenz INTs pro Periode Ausgangsfrequenz Bei einer gewünschten Ausgangsfrequenz von 1750Hz und 16 INTs (bzw. Werte) pro Periode komme ich auf einen comparewert von ca. 571. (Da sich ein Divisionsrest ergibt, sollte die theoretische Ausgangsfrequenz bei ca. 1751,3 Hz liegen) so g ;-)... - bis jetzt theoretisch alles schön und gut... - nach aufbau der Schaltung musste ich aber feststellen, dass die erzeugte Ausgangsfrequenz bei ca. 1645 Hz liegt. (comparewert 571) ...nach einigen Experimenten habe ich herausgefunden, dass man mit einem Comparewert von 537 relativ genau auf eine Ausgangsfrequenz von 1750 Hz kommt... - das finde ich auch schon mal nicht schlecht... :-) ...jetzt würde ich nur noch gerne verstehen, welchen Fehler ich bei der Berechnung des Comparewerts gemacht habe... :-) - Kann mir evtl. jemand einen Hinweis in dieser Richtung geben? :-) Vielen Dank & Viele Grüße Oliver
Deine Bedingung in der ISR ist falsch. Du gibts 16 mal den Wert aus und beim 17. Mal setzt du den Zähler zurück. Folge: dein Sinus ist um 1/16 zu langsam (und ist kein schöner sinus mehr) SIGNAL (SIG_OUTPUT_COMPARE1A) { if (i > 15) i=0; PORTB = pgm_read_byte(&sintable[i]); i++; }
Genau das war das Problem! :-)... - Vielen Dank für den Hinweis! ...ich hatte mir den code mindestens 100x angeschaut und immer nach einem fehler bei der Timerinitalisierung gesucht... :-) Jetzt stimmt auch die Frequenz :-)) - siehe Anhang. Besten Dank nochmals! :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.