Hallo kurze Frage an die Profis,
Das ist der DDS Algo von Jesper aus der Artikel Sammlung.
1
;mainloop
2
;
3
;r28,r29,r30isthephaseaccumulator
4
;r24,r25,r26istheaddervaluedeterminingfrequency
5
;
6
;addvaluetoaccumulator
7
;loadbytefromcurrenttableinROM
8
;outputbytetoport
9
;repeat
10
;
11
LOOP1:
12
addr28,r24;1
13
adcr29,r25;1
14
adcr30,r26;1
15
lpm;3
16
outPORTB,r0;1
17
rjmpLOOP1;2=>9cycles
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
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.
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.
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
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
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
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
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