2012-11-26 6 views
5

मैंने एएसएम को नियोजित एटम एवीआर पर एक डीडीएस प्रोजेक्ट पूरा किया है, और इस निष्कर्ष पर पहुंचा है कि 8 बिट लुक-अप टेबल और 8 बिट डीएसी बहुत अधिक मात्रा बनाते हैं कम आवृत्तियों पर विरूपण; बेहतर शब्दों की कमी के कारण, मुझे अपने ऑसिलोस्कोप पर सीढ़ी के प्रभाव के साथ साइन लहर मिल रही है।डीडीएस इंटरपोलेशन - 8 बिट एटम एवीआर एएसएम 12 बिट डीएसी

जाहिर है, अगर मैं एक बड़े एलपीएफ के साथ तरंगों को सुचारू बनाता हूं, तो मुझे उच्च आवृत्तियों में आयाम के साथ समस्याएं होती हैं।

सिद्धांत रूप में, 8 बिट से 12 बिट डीएसी से उन्नयन और 4 कम से कम महत्वपूर्ण बिट्स के साथ इंटरपोलेशन को नियोजित करने से मुझे अपने फ़िल्टर के कटऑफ पॉइंट को उच्च आवृत्तियों पर तरंगों के आयाम के साथ समस्याओं को कम करने के लिए पर्याप्त मात्रा में वृद्धि करने की अनुमति मिलनी चाहिए। मेरी समस्या यह है कि मेरे पास कोई संकेत नहीं है कि यह कैसे करें या यदि जिपर प्रभाव को हटाने का कोई आसान तरीका है .. शायद 12 बिट लुक-अप टेबल?

अब तक, मैंने एक अनंत लूप बनाया है और जब भी लूप एक चक्र पूरा करता है, तो लुक-अप तालिका से संबंधित सूचक की स्थिति के आधार पर डीएसी को एक मूल्य भेजा जाता है। यहां मैं उलझन में हूं। मैंने इस पर बहुत सारी जानकारी पढ़ी है और अभी भी एक कामकाजी उदाहरण नहीं मिला है। यदि मेरे पास अनंत लूप है, तो मुझे टेबल लुक-अप मानों के बीच इंटरपोलेशन मानों को कैसे भरना चाहिए? सबसे अच्छी चीज के बारे में जो मैं सोच सकता हूं वह है (ए + बी)/2; मैं शायद इसे कार्यान्वित कर सकता हूं और 512 पॉइंट लुक-अप टेबल के बराबर बिट या समकक्ष प्राप्त कर सकता हूं, लेकिन मुझे लगता है कि एक आसान तरीका या ऐसा कुछ है जो संभावित रूप से बेहतर परिणाम प्रदान कर सकता है। मुझे सी नहीं पता है या इसे कैसे नियोजित किया जाए, लेकिन अगर यह समझदार है तो मैं इसे आज़मा दूंगा।

वर्तमान में, मेरी घड़ी 1 एमएचजेड पर है और यदि आवश्यक हो तो मैं शायद 16 एमएचजेड पर जा सकता हूं।

यहाँ मेरी कोड का एक नमूना है:

; डिफ़ॉल्ट रूप से साइनवेव आउटपुट सेट करें

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 साइन तरंग पीढ़ी के लिए कई व्यावहारिक विकल्प की चर्चा।

संपादित सूत्र लागू करता पाठ्य पुस्तक रैखिक प्रक्षेप

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

तो कि y एक =, जब t = 0 और y = b, जब टी = 1। 8 से स्थानांतरित करने का अर्थ है कि गुणा के बाद इंटरपोलेशन शब्द टी को 256 से विभाजित किया गया है। अभिव्यक्ति LUT [r30 + 1] में मैं एक अंतर्निहित मॉड्यूलो 256 अंकगणित मान रहा हूं, क्योंकि आर 30 8-बिट है (है ना?)।

एलयूटी विस्तार को 12 बिट से अलग किया जाना चाहिए, क्योंकि इसके बजाय 4 से विभाजित करने से एलयूटी में मात्रात्मक त्रुटि बढ़ जाएगी।

enter image description here

प्रक्षेप LUT में हमेशा पूर्णांक सूचकांक के सापेक्ष होता है, भले ही कोई कई नमूने एक ही श्रेणी जैसे करने के लिए आते हैं। LUT 2 और LUT [3]। गणितीय लट [आर], एलयूटी [आर + 1] [आर -1], [आर] से अधिक सही है, लेकिन वास्तविक जीवन में कोई अंतर नहीं है, क्योंकि मानव श्रवण तंत्र में पूर्ण संदर्भ चरण नहीं है।

+0

आपके उत्तर के लिए धन्यवाद। हालांकि मैं इसे समझ में नहीं आता। सही 8 बिट्स क्यों बदलें? समीकरण का पहला भाग रजिस्टरों को बहुत आसानी से बह सकता है। लूट नहीं करेंगे [r30 + 1] तरंग के चरण को बदल दें, अगली बार पॉइंटर के संवेदनशील चरण तक अग्रिम नहीं? क्या पिछले सूचक चरण से पूछताछ करने के लिए और अधिक समझदारी नहीं होगी? –

संबंधित मुद्दे