Ich habe gerade ein DDS-Projekt auf einem Atmel AVR mit ASM abgeschlossen und bin zu dem Schluss gekommen, dass eine 8 Bit Look-Up-Tabelle und 8 Bit DAC zu viel Quantisierung erzeugen Verzerrung bei niedrigen Frequenzen; aus Mangel an besserem Wortlaut bekomme ich eine Sinuswelle mit einem Leiter-Effekt auf meinem Oszilloskop.DDS Interpolation - 8bit Atmel AVR ASM zu 12 bit DAC
Offensichtlich, wenn ich die Wellenform mit einem großen LPF glätten, habe ich Probleme mit der Amplitude in höheren Frequenzen.
Theoretisch sollte die Aufrüstung von einem 8 Bit auf 12 Bit DAC und die Verwendung von Interpolation mit den 4 niedrigstwertigen Bits den Grenzpunkt meines Filters deutlich genug erhöhen, um Probleme mit der Wellenformamplitude bei höheren Frequenzen zu verringern. Mein Problem ist, dass ich keine Ahnung habe, wie man das macht oder ob es einen einfacheren Weg gibt, den Reissverschluss-Effekt zu entfernen. Vielleicht 12-Bit-Look-Up-Tabellen?
Bisher habe ich eine Endlosschleife erstellt und jedes Mal, wenn die Schleife einen Zyklus beendet, wird ein Wert an den DAC gesendet, basierend auf der Position des Zeigers, der sich auf die Nachschlagetabelle bezieht. Hier bin ich verwirrt. Ich habe eine Menge Informationen darüber gelesen und habe immer noch kein funktionierendes Beispiel gefunden. Wenn ich eine Endlosschleife habe, wie soll ich die Interpolationswerte zwischen den Tabellennachschlagewerten stopfen? Über das Beste, was ich mir vorstellen kann, ist (a + b)/2; Ich kann das wahrscheinlich implementieren und ein zusätzliches Bit oder das Äquivalent einer Nachschlagetabelle mit 512 Punkten erhalten, aber ich würde gerne glauben, dass es einen einfacheren Weg oder etwas gibt, das möglicherweise bessere Ergebnisse liefern könnte. Ich weiß nicht, C oder wie man es anwendet, aber ich werde es versuchen, wenn es umsichtig ist.
Momentan ist meine Uhr bei 1MHz und ich könnte bei Bedarf zu 16MHz gehen. Hier
ist eine Probe von meinem Code:
; Setze Sinuswellenausgabe als Standard
ldi ZH, High(sine*2); setup Z pointer hi
ldi ZL, Low(sine*2) ; setup Z pointer lo
; Klarer Akkumulator
clr r29 ; clear accumulator
; Setup-Addierer-Register
ldi r24,0x50 ; Fine adder value change register
ldi r25,0x08 ; Middle adder value change register
ldi r26,0x00 ; Coarse adder value change register
LOOP1:
add r28,r24 ; 1 Adder values carry over to higher registers. Higher registers raise freq. in larger steps
adc r29,r25 ; 1
adc r30,r26 ; 1 r30 is database address pointer for Z register
lpm r0, Z ; 3 (Load Program Memory) Reads byte from database into the destination register based on Z pointer
out PORTD,r0
rjmp LOOP1 ; 2 => 9 cycles
Danke für Ihre Antwort. Ich verstehe es aber nicht. Warum acht Bits nach rechts verschieben? Der erste Teil der Gleichung könnte die Register sehr leicht überlaufen lassen. Würde nicht LUT [r30 + 1] die Phase der Wellenform ändern, nicht zum nächsten zeitempfindlichen Schritt des Zeigers vorrücken? Wäre es nicht sinnvoller, den vorherigen Zeigerschritt abzufragen? –