STM32F103, PWM als Tongerator

Gast #5612637
Lesenswert?

Hallo,

ich wollte eine PWM eines STM32 als Tongerator benutzten. Dafür müsste 
ich ja ständig den Presacaler bzw. den Period wert ändern. Es gibt 
Befehle für den Compare Wert zu ändern (das müsste ja im Prinzip die 
Lautstärke sein).

Wie kann ich Presacler und Period wärend der "Laufzeit" ändern. oder 
muss jedes mal den Timer abschlaten und mit dem neuen Tonwert 
initialisieren?

Dank und Gruß
Jan
#5612648
Lesenswert?

Jan schrieb:
> Es gibt
> Befehle für den Compare Wert zu ändern (das müsste ja im Prinzip die
> Lautstärke sein).

Was? Die Lautstärke hängt von der Amplitude ab, nicht vom 
Frequenzgehalt.

Jan schrieb:
> Wie kann ich Presacler und Period wärend der "Laufzeit" ändern.

Du kannst die entsprechenden Register während der Laufzeit ändern. Die 
Namen der Register kannst du dem Datenblatt entnehmen (Müsste TIMx_CCRx 
sein)
Gast #5612812
Lesenswert?

Möchtest du die PWM als "DAC" nutzen, d.h. pro Analog-Sample einen oder 
mehrere Timer-Durchläufe haben, ggf. mit externem Tiefpass, um so 
beliebige Wellenformen erzeugen zu können?
Oder mit der PWM direkt die hörbare Frequenz (< 20kHz) erzeugen, sodass 
man immer ein Rechteck hört?
#5612915
Lesenswert?

Jan schrieb:
> ich wollte eine PWM eines STM32 als Tongerator benutzten. Dafür müsste
> ich ja ständig den Presacaler bzw. den Period wert ändern. Es gibt
> Befehle für den Compare Wert zu ändern (das müsste ja im Prinzip die
> Lautstärke sein).

Das geht mit dem STM32 ziemlich elegant, indem du die Wellenform zuerst 
in einem Array anlegst und dann im Hintergrund per DMA als PWM an den 
Timer schicken lässt.
Gast #5613489
Lesenswert?

Ich wollte einfach Rechteck Töne erzeugen.

Ich glaube ich habe die entsprechenden Befehle gefunden.
1
    /*
2
    TIM3->ARR = period;        //TIM_Period  // TIM_SetAutoreload
3
    TIMx->CCR1 = compare;     // setcompare // TIM_SetCompare1
4
    TIMx->PSC = prescaler;      //prescaler    // TIM_SetIC1Prescaler
5
    */
6

7
    TIM_SetAutoreload(TIM3, period);
8
    TIM_SetCompare1(TIM3,compare);
9
    TIM_SetIC1Prescaler(TIM3, prescaler);

Das mit dem DMA Zugriff zwischen Speicher und PWM hört sich sehr 
interessant an. Hast du dazu ein Beispiel? Mit DMA habe ich noch nie 
etwas gemacht...
Gast #5613545
Lesenswert?

Jan schrieb:
> Wie kann ich Presacler und Period wärend der "Laufzeit" ändern. oder
> muss jedes mal den Timer abschlaten und mit dem neuen Tonwert
> initialisieren?

Nein, sowas geht ganz anders.

Zunächst stellst du dir die Periode deines PWM-Timers so ein, daß sie 
groß genug ist, um darin etwas mehr als sämtliche vorkommende 
Amplitudenwerte unterzubringen.

Also wenn du deine Töne mit 10 Bit Amplitudenauflösung abspielen willst, 
dann setzt du die Periode auf so etwa 1024+10+10, macht 1044. Das machst 
du, um mit der Amplitude nicht direkt an die Rails anzuecken, denn du 
mußt die PWM-Ausgabe ja analog weiterverarbeiten.

Dann stellst du den Prescaler so ein, daß sich mit Prescaler und 
Zählumfang von hier im Beispiel 1044 eine Audio-Samplerate deiner Wahl 
ergibt, die du auch noch per Interrupt verarbeiten kannst.

Dann stellst du den Comparewert auf Mitte ein, also 1024/2 + 10, macht 
522.

Dann hast du die Wahl:
a) du machst dir einen Ringpuffer ausreichender Größe und füllst ihn mit 
522.
b) du machst eine Variable, aus der dein Interruptprogramm erkennt, ob 
es was spielen soll oder nicht.

So, nun kannst du den PWM einschalten.

Im zugehörigen Interruptprogramm machst du folgendes:
Variante a) nimm den nächsten Wert aus dem Ringpuffer und schreibe an 
dessen Stelle 522 in den Ringpuffer. Dann wandelst du das Sample um: 
addiere 522 und schreib das in das Compare-register
Variante b) guck nach, ob du dudeln sollst. Wenn ja, dann nimm das 
nächste Sample aus deinem Puffer, wandle es wieder um (+522) und 
schreibe es in das Compareregister. Wenn nein, schreibe 522 in das 
Compareregister.

Hinter dem Ganzen auf der Pin-Seite mußt du natürlich das PWM per 
geeignetem Tiefpaß filtern, um die Samplefrequenz ausreichend zu 
dämpfen.

Damit kannst du Töne, aber auch kurze Sprachstücke wiedergeben. Für 
alles Weitere lies in der Lernbetty nach, da ist auch eine dezente 
Kompression der Audiodaten per SOL (Sierra-Format) dabei.

W.S.

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