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
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
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.