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
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)
>Was? Die Lautstärke hängt von der Amplitude ab, nicht vom >Frequenzgehalt. Schreib mal die Formel für die Messung der Lautstärke auf, dann wird's klarer ;-)
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?
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.
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...
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.
Jan schrieb: > Das mit dem DMA Zugriff zwischen Speicher und PWM hört sich sehr > interessant an. Hast du dazu ein Beispiel? Im Dokument "AN4776" (General-purpose timer cookbook) von ST ist viel Nützliches erläutert, was Du brauchen könntest. https://www.st.com/resource/en/application_note/dm00236305.pdf
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.