Tôi vừa hoàn thành một dự án DDS, trên một Atmel AVR sử dụng ASM, và đi đến kết luận rằng một bảng tra cứu 8 bit và 8 bit DAC tạo ra quá nhiều lượng tử hóa biến dạng ở tần số thấp; vì thiếu từ ngữ tốt hơn, tôi nhận được một làn sóng sin với hiệu ứng bậc thang trên dao động của tôi.DDS Interpolation - 8bit Atmel AVR ASM tới 12 bit DAC
Rõ ràng, nếu tôi làm mịn dạng sóng với LPF lớn, tôi gặp vấn đề với biên độ ở tần số cao hơn. Về lý thuyết, nâng cấp từ 8 bit lên 12 bit DAC và sử dụng nội suy với 4 bit quan trọng nhất sẽ cho phép tôi nâng điểm cắt của bộ lọc lên một lượng đủ lớn để giảm bớt các vấn đề với biên độ dạng sóng ở tần số cao hơn. Vấn đề của tôi là tôi không có một đầu mối làm thế nào để làm điều này hoặc nếu có một cách dễ dàng hơn để loại bỏ các hiệu ứng dây kéo .. có lẽ 12 bit bảng tra cứu? Cho đến nay, tôi đã tạo ra một vòng lặp vô hạn và mỗi khi vòng lặp hoàn thành một chu kỳ, một giá trị được gửi đến DAC dựa trên vị trí của con trỏ liên quan đến bảng tra cứu. Đây là nơi tôi bị lẫn lộn. Tôi đã đọc tấn thông tin về điều này và vẫn chưa tìm thấy một ví dụ làm việc. Nếu tôi có một vòng lặp vô hạn, làm thế nào tôi phải nhồi nhét các giá trị nội suy giữa các giá trị tra cứu bảng? Về điều tốt nhất mà tôi có thể nghĩ đến là (a + b)/2; Tôi có thể có thể thực hiện điều này và nhận thêm một chút hoặc tương đương với bảng điểm 512 điểm, nhưng tôi muốn nghĩ rằng có một cách dễ dàng hơn hoặc thứ gì đó có khả năng mang lại kết quả tốt hơn. Tôi không biết C hoặc làm thế nào để sử dụng nó, nhưng tôi sẽ cung cấp cho nó một thử nếu nó là thận trọng.
Hiện tại, đồng hồ của tôi ở mức 1MHZ và có thể tôi đến 16MHZ nếu cần.
Đây là mẫu mã của tôi:
; Đặt đầu ra sinewave làm mặc định
ldi ZH, High(sine*2); setup Z pointer hi
ldi ZL, Low(sine*2) ; setup Z pointer lo
; Clear accumulator
clr r29 ; clear accumulator
; Cài đặt bộ cộng đăng ký
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
Cảm ơn câu trả lời của bạn. Tôi không hiểu nó. Tại sao phải thay đổi 8 bit? Phần đầu tiên của phương trình có thể rất dễ dàng tràn các thanh ghi. Sẽ không LUT [r30 + 1] thay đổi pha của dạng sóng, không tiến tới bước nhạy cảm thời gian tiếp theo của con trỏ? Nó sẽ không có ý nghĩa hơn để truy vấn bước con trỏ trước đó? –