Forum: Mikrocontroller und Digitale Elektronik DDS, Phasenakkumulator


von clonephone (Gast)


Lesenswert?

Hallo kurze Frage an die Profis,

Das ist der DDS Algo von Jesper aus der Artikel Sammlung.
1
; main loop
2
;
3
;  r28,r29,r30 is the phase accumulator
4
;    r24,r25,r26 is the adder value determining frequency
5
;
6
;   add value to accumulator
7
;  load byte from current table in ROM
8
;  output byte to port
9
;  repeat 
10
;
11
LOOP1:
12
    add    r28,r24      ; 1
13
    adc    r29,r25      ; 1
14
    adc    r30,r26      ; 1
15
    lpm            ; 3
16
    out    PORTB,r0    ; 1
17
    rjmp  LOOP1      ; 2 => 9 cycles

Er verwendet einen 24 Phasenakumulator. Die Sinustabelle hat 256 Werte. 
So wie ich den Code verstehe verwendet er nur das HighByte des 24Bit 
Akkumulators für die Phasen/Amplituden Umwandlung?

Oder ?

danke clonephone

von Achim (Gast)


Lesenswert?

Das verstehst du richtig.

von clonephone (Gast)


Lesenswert?

Meint ihr das es möglich ist 16 solche accumulatoren zu rechenen auf 1 
16Bit Prozessor ?  Ich muss 16 Signale erzeugen 0-500Hz.

thx

von Benedikt K. (benedikt)


Lesenswert?

Prinzipiell spricht nichts dagegen.
Sagen wir mal du verwendest eine um den Faktor 10 höhere Samplerate (um 
den Tiefpass weniger kritisch zu machen), also 10kHz, dann sind 160000 
Additionen + Tabellenzugriffe usw. notwendig, falls dir 0,15Hz 
Frequenzauflösung reichen.
Das sollte für die meisten Prozessoren kein allzu großes Problem sein.

von clonephone (Gast)


Lesenswert?

Du meinst das jetzt nicht ironisch oder ?
Das mit den Additioenen + Tabellen Zugriffe war mir klar. :-)

Also du meinst es ist machbar oder ?

thx

von Benedikt K. (benedikt)


Lesenswert?

Ja, ich denke schon. Ich gehe mal grob von rund 10-20 Takten pro DDS 
aus, dann wären das bei 10kHz 1,6-3,2MHz minimale Taktfrequenz. Sollte 
also für die meisten µC machbar sein.

von clonephone (Gast)


Lesenswert?

Okay danke.

von clonephone (Gast)


Lesenswert?

Hallo,

Ich denke ich habe das Prinzip von DDS verstanden, aber ein paar Sachen 
sind noch unklar. Ich habe einen 16Bit Phasenakku und verwende nur das 
HighByte für die LUT. Mein DDS Clk ist 10kHz.

Frequnz Tuning Word(FTW) = Frequenz * 2^n / DDS_Clk;

Wenn ich einen 16Bit Phasenakku verwende aber für die LUT nur das High 
Byte nehme ist dann n = 256 oder n = 65535. Ich meine 65535.

Also ich möchte eine Frequenz von 20 Hz. Das heißt, falls das n von oben 
stimmt:

==>  FTW = 20Hz * 2^16 / 10000Hz = 131,072

==>  Problem ich möchte den Phasenakku nicht mit float rechnen hätte 
aber gerne eine genaue Frequenz! Gibts es da einen Trick via Fixpoint 
oder so. Die Taktrate kann ich nur schlecht ändern.

Es gibt ja im Forum einen Beitrag wo das mit Fixpoint und DDS erklärt 
wird. Aber eine 8.8 Fixpoint ist ja nicht gerade gut finde ich weil dann 
kann ich ja maximal 255.0Hz einstellen, da müsste man dann den 
Phasenakku vergrössern was für einen 16Bitter wieder schlecht ist.

Weitere Frage: Wenn man genug Speicher hat ist es besser eine LUT mit 
1024 zu nehmen?

Vielen Dank im Voraus

von hans (Gast)


Lesenswert?

Hallo clonephone,

ich gehe mal davon aus, daß die 10 KHz die Frequenz ist, mit der du
im Timerinterrupt einen Tabellenwert holst und ausgibst.
Deine Tabelle hat 256 Einträge für einen kpl. Sinus.

Du brauchst also 256 Interrupts für ein Signal.
10KHz/256 = 39,0625 Hz = Grundfrequenz.

für 20 Hz wäre dein FTW dann wie von dir auch ausgerechnet
131,072. (meine Formel stimmt!)

Wenn du das mal als 16 bit wert betrachtest 0000 0000 1000 0011

in Worten 0 ganze und 131/256 Nachkomma.

Damit hast du luft nach oben.

Für die 39,.. ist das FTW 0000 0001 0000 0000

Für Frequenzen bis 500 Hz sind die 10 KHz etwas langsam
(10KHz/500Hz = 20) da in der Tabelle Sprünge von 20
auftreten. Besser wäre z.B. 50-100KHz.
Eine größere Tabelle würde das problem nur verschärfen,
da die Grundfrequenz absinken würde und die Sprünge
entsprechend größer.

gruß hans

von clonePhone (Gast)


Lesenswert?

Hallo hans,

Danke für deine Antwort.

>ich gehe mal davon aus, daß die 10 KHz die Frequenz ist, mit der du
>im Timerinterrupt einen Tabellenwert holst und ausgibst.
>Deine Tabelle hat 256 Einträge für einen kpl. Sinus.

==> genau so mach ich es.

>Du brauchst also 256 Interrupts für ein Signal.
>10KHz/256 = 39,0625 Hz = Grundfrequenz.

okay war mir klar.


>für 20 Hz wäre dein FTW dann wie von dir auch ausgerechnet
>131,072. (meine Formel stimmt!)

ja also die mit 2^16 rechnen habe ich mir eh gedacht.

>Wenn du das mal als 16 bit wert betrachtest 0000 0000 1000 0011

==> ja und die komma ,072 ?


>in Worten 0 ganze und 131/256 Nachkomma.

?


>Damit hast du luft nach oben.
>Für die 39,.. ist das FTW 0000 0001 0000 0000
>Für Frequenzen bis 500 Hz sind die 10 KHz etwas langsam
>(10KHz/500Hz = 20) da in der Tabelle Sprünge von 20
>auftreten.

Wie meinst das mit den Sprüngen ? Klar ich habe nur 20 Punkte bei 500 Hz 
Aber das müsste allemal reichen, meinst du nicht?

>Besser wäre z.B. 50-100KHz.
Ja ist klar, Aber ich muss 16 mal sowas rechnen auf einer 16 Bit 
Maschine. Ich habe eh schon Mühe es mit 10kHz zu machen. Bzw. ich weis 
noch gar nicht ob es machbar ist bzw ob es funktioniert.

>Eine größere Tabelle würde das problem nur verschärfen,
>da die Grundfrequenz absinken würde und die Sprünge
>entsprechend größer.

ok

von hans (Gast)


Lesenswert?

Hallo clonephone,

war noch Eiersuchen.

==> ja und die komma ,072 ?

Du hast mit den 131 ja schon Nachkommastellen. Die 0,072 sind
der Fehler, der durch die begrenzte Bitzahl auftritt. Du hast
nur 8 Bit für die Nachkommastellen, snst bräuchtest du einen
breiteren Zähler (z.B. 2^24).
Diesen Fehler hat jedes Digitale System. Auch AD- und DA-Wandler
haben diese Stufungen.

Wenn du mit den 131 zurückrechnest kommst du auf 19,99 Hz
bei 130 sind es 19,84 und bei 132 dann 20,14 Hz.
Also schon eine recht feine Auflösung.

>Wie meinst das mit den Sprüngen ? Klar ich habe nur 20 Punkte bei 500 Hz
>Aber das müsste allemal reichen, meinst du nicht?

Da es ein Sinussignal ist und damit keine riesigen Sprunge hat
geht es schon, sieht aber nicht mehr sehr gut aus.
Er macht keine 20 Sprünge sondern Sprünge mit der Weite 20.
Ein Signal besteht dann nur noch aus ca. 12-13 Stützstellen.

Wenn man das noch weiter erhöht kommt man schlieslich zu einem
Rechteck mit hier 5 KHz bei FTW = 32768  ( 1000 0000 0000 0000 ).

Auf einem 16BIT µC sollte ein Kanal 10-12 Taktzyklen dauern.
Dies wäre Vollauslastung bei 2 MHz. Dein Prozessor ist bestimmt
schneller.

Schon eine Verdoppelung der Grundfrequenz wäre ein deutlicher
Gewinn.

gruß hans

von clonePhone (Gast)


Lesenswert?

Also müsste es machbar sein. Mal sehen vielleicht kann ich auch mit dem 
DDS_Clock etwas nach oben.

Danke hans. Ich berichte dann.

gruss clonephone

von manfred (Gast)


Lesenswert?

Der Beitrag ist schon älter, aber bei 500Hz 256size Lookup und 
Phasenakku von 32 Bit hab ich doch 20 Stützstellen die ich heraushole 
aus der Lookup.
Wieso kommt ihr da auf 12/13 Stüztstellen?

Ich hab genau so was implementiert wenn ich den lut_index ausgeben dann 
sind es auch 20 bei einer Periode.


lg

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.