www.mikrocontroller.net

Forum: Compiler & IDEs Sinus mit atmega16 erzeugen


Autor: Oliver P. (olipir15)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Werner Hoch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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++;
}

Autor: Oliver P. (olipir15)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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! :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.