2012-11-26 26 views
5

我剛剛完成了採用ASM的Atmel AVR上的DDS項目,並得出結論:8位查找表和8位DAC會產生過多的量化低頻失真;由於缺乏更好的措辭,我在示波器上得到了一個帶有階梯效應的正弦波。顯然,如果我用大的LPF消除波形,我在較高頻率時會出現振幅問題。理論上,從8位升級到12位DAC並採用4位最低有效位插值應該允許我將濾波器的截止點提高足夠多,以緩解高頻率下波形幅度的問題。我的問題是,我沒有線索如何做到這一點,或者如果有更簡單的方法來刪除拉鍊效果..也許12位查找表?DDS插值 - 8位Atmel AVR ASM至12位DAC

到目前爲止,我創建了一個無限循環,每當循環完成一個循環時,就會根據與查找表相關的指針的位置向DAC發送一個值。這是我感到困惑的地方。我已經閱讀了大量的這方面的信息,但還沒有找到一個工作的例子。如果我有一個無限循環,我該如何填充表格查找值之間的插值?關於我能想到的最好的事情是(a + b)/ 2;我大概可以實現這一點,並獲得額外的一點或512點查找表的等價物,但我想認爲有一個更簡單的方法或可能提供更好的結果的東西。我不知道C或如何使用它,但如果它是謹慎的,我會試一試。

目前,我的時鐘在1MHZ,如果有必要,我可能會到16MHZ。

下面是我的代碼示例:

;設置正弦波輸出爲默認值

ldi  ZH, High(sine*2); setup Z pointer hi 
    ldi  ZL, Low(sine*2) ; setup Z pointer lo 

;清除累加器

clr  r29    ; clear accumulator 

;設置加法器註冊

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 

回答

2

如果您的LUT有256個條目,你可以先用寄存器R29(,顯然從0到255)爲兩個連續樣本之間的比例因子。

Output = (LUT[r30] * (256 - r29) + LUT[r30+1] * r29) >> 8;

Also this thread討論了正弦波產生許多切實可行的辦法。

EDIT的公式實現教科書線性插值

y = a*(1-t) + b*t, with 0<=t<1 

,從而y = A,當t = 0和y = B,當t = 1。移位8意味着插值項t在乘法後被除以256。在表達式LUT [r30 + 1]中,我假設隱式模256算術,因爲r30是8位(不是嗎?)。

LUT擴展到12位必須單獨完成,因爲除以4將會增加LUT中的量化誤差。

enter image description here

內插在LUT發生總是相對於整數索引,如果無論許多樣品下降到相同的範圍例如。 LUT 2和LUT [3]。數學上LUT [R],LUT [R + 1]大於[R-1],[R],但在現實生活中是沒有區別的,因爲人類audatory系統不具有絕對基準相位更正確。

+0

謝謝您的回答。但我不明白。爲什麼右移8位?等式的第一部分很容易溢出寄存器。 LUT [r30 + 1]不會改變波形的相位,不會前進到指針的下一個敏感步驟?查詢以前的指針步驟不是更有意義嗎? –