Forum: Mikrocontroller und Digitale Elektronik PWM zu Sinus


von Samuel (Gast)


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

von Max H. (hartl192)


Angehängte Dateien:

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.

: Bearbeitet durch User
von Simon K. (simon) Benutzerseite


Lesenswert?

Das Stichwort ist DDS. Direct Digital Synthesis

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
Noch kein Account? Hier anmelden.