erzeugen eines sinus mit variabler frequenz

OP #489511
Lesenswert?

Hi.
Ich bin gerade ein bisschen am Testen mit nem ATmega32 und wollte jetzt 
mal nen Sinus mit variabler Frequenz erzeugen, um schöne Töne ausgeben 
zu können und später vielleicht auch mehrere Töne gleichzeitig ausgeben 
zu können (Überlagerung).

Ich hab mir beim Programmstart ne Sinus-Tabelle mit 64 Einträgen 
angelegt:
for (i = 0; i < 64; i++)
        sintab[i] = (127. * sin(2  PI  i /64)) + 127.;

Im weiteren Verlauf des Programms nehm ich immer einen Wert davon, geb 
ihn über eine 8-Bit-PWM (Timer 2) aus und erhöhe den Zähler, der auf 
eine Stelle in der Tabelle zeigt.
Über nen Tiefpass am Ausgangs-Pin ergibt sich dann auch ein schöner 
Sinus mit ca. 1 Hz bei Taktfrequenz 1 MHz.

Wie kann ich diese Frequenz jetzt zur Laufzeit ändern?

Danke schon mal.
#489534
Lesenswert?

@johnny.m: Eben nicht!

@kernel: Du mußt die Frequenz ändern, mit der Du die Schleife aufrufst, 
die einen Wert aus der Tabelle holt, ihn ins PWM-Register schreibt und 
den Zähler erhöht. Dabei solltest Du daran denken, daß die maximale 
Frequenz, die Du über einen PWM-Ausgang ausgeben kannst um ein 
vielfaches unter der PWM-Frequenz liegt. Schließlich ist der PWM ein 
Tiefpass nachgeschaltet, daß die Aufgabe hat, die eigentlich 
PWM-Frequenz rauszufiltern. Je nachdem wie steil Dein Filter ist und wie 
sauber Du das Signal haben möchtest, mußt Du den Abstand von 
PWM-Frequenz und maximaler Ausgabefrequenz wählen.

Mit welcher Frequenz arbeitet denn Deine PWM?

Allgemein kann man aber sagen, daß PWM eine schlechte Methode ist, ein 
Audiosignal mit einem µC zu erzeugen. Da würde ich eher so einen ganz 
simplen D/A-Wandler, bestehend aus ein paar Widerständen an einem 
acht-bit-Port verwenden - mal vorausgesetzt, Du hast noch sowas frei.

Markus_8051
Gast #489537
Lesenswert?

Das ist eine normale "DDS"-Sinuserzeugung. Um die Frequenz zu ändern 
variiert man die Sprungweite in der Tabelle, die Zeit zwischen den 
Tabellenwertausgaben bleibt konstant.
Gast #489695
Lesenswert?

Ja sicher, jeder DDS hat Jitter. Je höher die Frequenz desto schlimmer, 
die Stufen sind ja ab der niedrigsten Frequenz gleich. Die Sinustabelle 
muß möglichst groß sein, so dass die niedrigste Frequenz gerade jeden 
Tabellenwert einmal aufruft. Mit PWM wird die Auflösung nochmal 
verschlechtert, denn die muß in der Frequenz noch deutlich über dem 
Tabellenauslesetakt liegen.
Gast #489751
Lesenswert?

Bei Verwendung des 16Bit Timers bekommt man mit einem 3,68640MHz Quarz 
eine Auflösung von delta_f=56,25Hz. Bei einer Periode des Sinus mit 8Bit 
ist die max. Frequenz f_max=13,619kHz.

delta_f = 3.68640MHz / 2^16

f_max = 2^8 * 3,68640MHz / 2^16

init = f_soll * 2^16 / 3.6864MHz

Ich weiß jetzt nur nicht ob man den Timer auch mehr als "eins" erhöhen 
kann.


for (;;)
TEMP = TEMP + init;

u_sin = sintab[TEMP(15:8)];

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren