PWM zu Sinus

Gast #3631023
Lesenswert?
• ▲
▼
Guten Abend alle zusammen :)

Momentan bin ich gerade an einer Arbeit, in welcher ich mittels PWM 
einen Sinus erzeugen soll. Habe mich bereits in diversen Foren 
durchgelesen.

Zuerst einmal zum bereits bestehenden Projekt:

- uP = PIC32MX250F128B
- PWM wird momentan mit einer Frequenz von 50kHz ausgegeben
- mit einer Frequenz von 25kHz wird die Interrupt-Service-Routine 
aufgerufen

#define - Code:


#define SYS_FREQ               (48000000L)  //Systemfrequenz
#define PB_DIV               1           //Divisor auf 1
#define PRESCALE             1           //Prescale auf 1
#define Interrupts_per_Sec   25000
#define T1_TICK 
(SYS_FREQ/PB_DIV/PRESCALE/Interrupts_per_Sec)
                             //Preload Wert für Interrupt


#define PWM_FREQ            (Interrupts_per_Sec * 2)
#define T2_TICK             (SYS_FREQ/PB_DIV/PRESCALE/PWM_FREQ)
                             //Preload Wert für PWM



Nun würde ich gerne mit diesem PWM einen Sinus generieren.
Meinen externen DAC habe ich als 3stufiges RC-Glied aufgebaut mit den 
Werten: R = 1kOhm  C = 4.7nF
Nun kann man mit dem Verändern des Tastgrades des PWMs die Amplitude des 
Sinus definieren.
Mein Ziel ist es, an einen Lautsprecher den Ton C4 (Grundfrequenz von 
261.626Hz) auszugeben. Jedoch geht es mir gerade nur um die korrekte 
Sinuserzeugung mit diesem PWM.
Wie gehe ich am besten vor?
Meiner Meinung nach, sollte ich ein Array erstellen, welches die 
verschiedenen Duty Cycle Werte (am besten in %-Zahlen) beinhaltet. Doch 
wie rechne ich diese Werte aus? Was gibt es für eine Formel?

Der Ton C4 hat ja eine Frequenz von 261.626Hz, das entsprich ja die 
360Grad in 3.82225ms. Meine ISR wird im 40uS-Takt aufgerufen. Das 
heisst, dass die ISR 95.556mal in einem ganzen Sinus aufgerufen wird. 
Gehen wir von 96mal aus. Somit kann ein Sinus von 260.41666Hz (beste 
Annäherung) generiert werden, stimmt das? Diese kleine Abweichung sollte 
kein Problem sein, ansonsten würde ich dann halt die Frequenz des 
Interruptes verdoppeln. Bei jedem Interrupt-Aufruf wird dann der 
Duty-Cycle-Wert angepasst. Wie gesagt, ich denke am besten mit einem 
Array welches alle Werte beinhaltet und der Interrupt zählt das Array 
hoch. Oder gibt es doch eine einfachere Berechnungsformel?

Hauptproblem = Formel zur präzisen Veränderung des Duty-Cycle-Wertes.
 -> bitte möglichst simpel Formel beschreiben ;)

Bei allfälligen nicht vorhandenen Infos gebe ich diese nach.
Ein grosses Dankeschön schon im Voraus

samuel
#3631032
Lesenswert?
• ▲
▼
Samuel schrieb:
> Meiner Meinung nach, sollte ich ein Array erstellen, welches die
> verschiedenen Duty Cycle Werte (am besten in %-Zahlen) beinhaltet.
Ich wäre für die fertigen PWM Werte und nicht %.

>Doch wie rechne ich diese Werte aus? Was gibt es für eine Formel?
Ja, den Sinus bzw. dessen Taylor-Entwicklung

Ich habe meine 10bit PWM Sinus Tabelle mit 250 Schritten für 360° so 
erstellt:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <math.h>
4

5
#define PI 3.1415926535897932384626433832795
6
#define N 250
7

8
int main()
9
{
10
    int i;
11
    unsigned int sinus;
12
    FILE *datei;
13

14

15
    datei=fopen("D:\\Desktop\\Sinus.txt","w");
16

17

18
    fprintf(datei,"unsigned int sin_tab[]={");
19

20
    for(i=0;i<N;i++)
21
    {
22
        sinus=(unsigned int)(sin(2*PI*i/N)*512+512);
23

24
        printf("%i   \t%i\n",i,sinus);
25
        fprintf(datei,"%i,",sinus);
26
    }
27
    fprintf(datei,"};");
28
    fclose (datei);
29

30
    return 0;
31
}

Falls es dir hilft, im Anhang ein Code um 50Hz Sinus mit einem 
PIC12F1840 zu erzeugen. Die Tabelle wurde mit dem Code oben erstellt.
Angehängte Dateien:

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.