我刚刚在使用 ASM 的 Atmel AVR 上完成了一个 DDS 项目,得出的结论是 8 位查找表和 8 位 DAC 在低频下会产生过多的量化失真;由于缺乏更好的措辞,我在示波器上得到了一个带有梯形效果的正弦波。
显然,如果我用大 LPF 平滑波形,我会遇到更高频率的振幅问题。
从理论上讲,从 8 位 DAC 升级到 12 位 DAC 并使用 4 个最低有效位的插值应该允许我将滤波器的截止点提高到足够显着的量,以缓解较高频率下的波形幅度问题。我的问题是我不知道如何做到这一点,或者是否有更简单的方法来消除拉链效果。也许是 12 位查找表?
到目前为止,我已经创建了一个无限循环,每次循环完成一个循环时,都会根据与查找表相关的指针的位置向 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
循环1:
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