
यह लेख
VHDL FPGA प्रोग्रामिंग में शुरुआती लोगों के लिए है और जो इसे करना सीखना चाहते हैं। इससे पहले, PIC नियंत्रक पर लागू समान कार्य के साथ एक
लेख पहले से ही हैबर पर विचार किया गया था। और इस लेख में हम FPGA का उपयोग करके एलईडी की चमक को बदलने के बारे में बात करेंगे।
तो, काम का लक्ष्य:
पीडब्लूएम की अवधारणा को मास्टर करना और एलईडी की चमक को बदलने में इसे लागू करना। कार्यान्वित करने के लिए,
Xilinx ISE प्रोजेक्ट नेविगेटर v12.3 विकास वातावरण में VHDL प्रोग्रामिंग भाषा का उपयोग करें।
लक्ष्य को प्राप्त करने के लिए आगे बढ़ते हैं
कार्यान्वयन के लिए, हमें FPGAs के साथ कुछ हार्डवेयर की आवश्यकता है, मैंने स्पार्टन -3 ई स्टार्टर किट (
डेटाशीट ) चुना, जो हाथ पर था। Xilinx ISE प्रोजेक्ट नेविगेटर (मेरे पास संस्करण 12.3 स्थापित है) को स्थापित करना भी आवश्यक है। मूल रूप से, सब कुछ काम करने के लिए तैयार है। यह केवल बोर्ड को पावर कनेक्ट करने और इसे आगे की प्रोग्रामिंग के लिए यूएसबी के माध्यम से कंप्यूटर से कनेक्ट करने के लिए बना हुआ है।
भाग 1. एलईडी की चमक को बदलने का सिद्धांत।
एलईडी की चमक को स्थिर वोल्टेज के विभिन्न मूल्यों को लागू करके इसे समायोजित किया जा सकता है (उदाहरण के लिए, एक चर अवरोधक द्वारा)। लेकिन हमारे बोर्ड पर वैरिएबल रेसिस्टर्स के बिना एलईडी हैं, जो '1' और 'फुल ब्राइटनेस' या '0' में वैल्यू ले सकते हैं। तो फिर कैसे इस तरह के एक सरल डिवाइस की चमक को समायोजित करने के लिए? इसका जवाब PWM है। पूरी बात यह है कि हम इस एलईडी को इतनी जल्दी "ब्लिंक" करेंगे कि पलक झपकना भी हमारी आंख को दिखाई नहीं देगा, लेकिन हम सिर्फ एक मंद रोशनी वाली एलईडी देखेंगे। अधिक सटीक होने के लिए, यह सिर्फ इतना है कि इग्निशन के दौरान एलईडी में एक क्षणिक है, अर्थात यह तुरंत प्रकाश नहीं करता है। यह वह है जो हम उपयोग करते हैं, यूनिट को बहुत कम समय के लिए देते हैं, ताकि एलईडी को पूरी चमक में प्रकाश करने का समय न हो।
भाग 2. एक नई परियोजना का निर्माण।
ISE प्रोजेक्ट नेविगेटर डाउनलोड करें और फ़ाइल -> नई परियोजना को रोकें। हम प्रोजेक्ट का नाम लिखते हैं (मेरे पास shim_habr है), शीर्ष स्तर के स्रोत प्रकार को बचाने के लिए निर्देशिका का चयन करें: नीचे से एचडीएल। अगला क्लिक करें।

अगला, FPGA का चयन करें। मेरे मामले में, परिवार: स्पार्टन 3 ई; डिवाइस: XC3S500E; पैकेज: FG320; गति: -4। इन सभी डेटा को चिप पर ही देखा जा सकता है, या डेटाशीट में देख सकते हैं।

अगला, पसंदीदा भाषा चुनें: वीएचडीएल, अगला क्लिक करें और फिर समाप्त करें।

प्रोजेक्ट बना है। अब हमें इसमें एक मॉड्यूल जोड़ने की आवश्यकता है, जिसमें हम एलईडी के तर्क का वर्णन करेंगे। ऊपरी बाईं ओर, नया स्रोत बटन ढूंढें और उस पर क्लिक करें:

दिखाई देने वाली विंडो में, VHDL मॉड्यूल का चयन करें और कोई भी फ़ाइल नाम लिखें (आप इसे shim_habr प्रोजेक्ट के साथ नाम दे सकते हैं)। अगला क्लिक करें।

अब हमें परियोजना में उपयोग किए जाने वाले पैरों को सेट करने की आवश्यकता है। अब आप ऐसा नहीं कर सकते और इस चरण को छोड़ दें, और फिर सब कुछ हाथ से लिखें। लेकिन चूंकि हमारे प्रोजेक्ट के लिए हमें केवल तीन पैरों की जरूरत है, मैंने उन्हें यहीं प्रवेश दिया। तो, हमें 50 मेगाहर्ट्ज बोर्ड पर स्थापित क्वार्ट्ज से संदर्भ आवृत्ति की आवश्यकता है, C9 नाम के साथ FPGA से पैर तक जुड़ा हुआ है, और हम दो एलईडी का भी उपयोग करेंगे जो पहले से बोर्ड पर स्थापित हैं। मान लीजिए कि ये E12 और F12 नामों के तहत FPGA पैरों से जुड़े दो सही एलईडी हैं। क्वार्ट्ज लेग क्लक को कॉल करें, दिशा सेट करें: चूंकि हम आवृत्ति को पढ़ेंगे, और एल ई डी के साथ पैरों का नेतृत्व किया जाता है और led2 का मूल्य दिशा के साथ होता है: OUT, क्योंकि हम उन्हें प्रबंधित करेंगे।

अगला क्लिक करें, फिर समाप्त करें। हम पहले से भरे हुए प्रोजेक्ट के I / O पोर्ट के साथ खोले गए टेक्स्ट एडिटर को देखते हैं।
संस्था shim_habr है
पोर्ट ( clk : STD_LOGIC में ;
led1 : STD_LOGIC ;
एलईडी 2 : एसटीडी_ओओजीआईसी ) ;
अंत shim_habr ;
जैसा कि मैंने कहा, आप पिछले चरण को छोड़ सकते हैं और इसे मैन्युअल रूप से दर्ज कर सकते हैं। अगला, हमें पोर्ट नामों को FPGA पैरों के नाम पर मैप करने की आवश्यकता है। पदानुक्रम में फ़ाइल नाम shim_habr.vhd पर राइट-क्लिक करें और नया स्रोत चुनें।

खुलने वाली विंडो में, कार्यान्वयन बाधा फ़ाइल चुनें और इस पिन फ़ाइल को कॉल करें। अगला क्लिक करें, फिर समाप्त करें।

खुलने वाली खाली फ़ाइल में, निम्नलिखित लिखें:
NET "clk" LOC = "C9" ;
NET "led1" LOC = "F12" ;
NET "led2" LOC = "E12" ;
सहेजें।
पैरों की संख्या को डेटाशीट में देखा जा सकता है, या हमारे मामले में, हमारे लिए खोज को सरल बनाया गया था - संख्याओं को वांछित परिधीय के बगल में सीधे बोर्ड पर देखा जा सकता है:

भाग 3. एलईडी की निरंतर चमक को प्रोग्रामिंग करना।
Shim_habr.vhd फ़ाइल पर जाएँ और कोड लिखें:
वास्तुकला shim_habr का व्यवहार है
निरंतर clk_freq : पूर्णांक : = 50 _000_000 ; - क्वार्ट्ज आवृत्ति
निरंतर shim_freq : पूर्णांक : = 10 _000 ; - PWM आवृत्ति
निरंतर max_count : पूर्णांक : = clk_freq / shim_freq ; - पीडब्लूएम क्षमता
संकेत गणना : पूर्णांक सीमा 0 से अधिकतम_कर : = 0 ; - आवृत्ति विभक्त काउंटर
निरंतर पोरोग : पूर्णांक : = max_count / 48 ; - तार्किक इकाई की पल्स चौड़ाई
शुरू करना
प्रक्रिया ( clk )
शुरू करना
अगर उठ रहा है तो ( clk ) तब
अगर गिनती = max_count तो
गिनती <= 0 ;
अन्यथा
गिनती <= गिनती + 1 ;
अंत यदि ;
अंत यदि ;
अंतिम प्रक्रिया ;
led1 <= ' 1 ' जब गिनती < porog और ' 0 ' ;
led2 <= ' 1 ' ;
अंत व्यवहार ;
अब देखते हैं कि यह कोड क्या करता है। सबसे पहले, लाइन led2 <= '1' पर ध्यान दें। हम पूरी चमक पर दूसरी एलईडी को रोशनी देते हैं, वहां एक तार्किक इकाई की आपूर्ति करते हैं, ताकि हमारे पास पहली एलईडी की चमक की चमक के साथ तुलना करने के लिए कुछ हो। अगला, हम घोषित रजिस्टरों और स्थिरांक को देखते हैं। Clk_freq निरंतर हर्ट्ज में क्वार्ट्ज की आवृत्ति को संग्रहीत करता है; shim_freq हर्ट्ज में PWM की आवृत्ति है। तदनुसार, पीडब्लूएम अवधि प्राप्त करने के लिए हमें पीडब्लूएम आवृत्ति द्वारा घड़ी की आवृत्ति को विभाजित करना आवश्यक है, और हम पीडब्लूएम अवधि के अनुरूप मुख्य क्वार्ट्ज के घड़ी चक्रों की संख्या प्राप्त करेंगे। संक्षेप में, यह पीडब्लूएम की चौड़ाई होगी। विभाजन का परिणाम निरंतर max_count को लिखा जाता है। इसके बाद, एक काउंटर गणना बनाएं, जो 50 मेगाहर्ट्ज की आवृत्ति पर 0 से अधिकतम_काउंट तक चक्र होगा। हम प्रक्रिया प्रक्रिया (clk) बनाते हैं। यदि राइजिंग_जेड (clk) की स्थिति तब क्वार्ट्ज से अगले "टिक" की प्रतीक्षा करती है, और यदि ऐसा होता है, तो यह यूनिट के लिए गिनती जोड़ता है, अगर यह अधिकतम मान तक गिना गया है। अगला, प्रक्रिया के बाहर, हम लाइन लिखते हैं
led1 <= ' 1 ' जब गिनती < porog और ' 0 ' ;
यही है, एक तार्किक इकाई एलईडी पर लटकाती है जब हमारा काउंटर कुछ थ्रेशोल्ड पोरोग मूल्य से कम होता है (मेरे लिए यह पूरी अवधि का 1/48 है, निरंतर घोषणा देखें), एलईडी पर शेष अवधि तार्किक शून्य लटकाती है। यह आंकड़ा में स्पष्ट रूप से दिखाया जा सकता है:

भाग 4. फ़र्मवेयर।
हम सभी परिवर्तनों को सहेजते हैं, पदानुक्रम में shim_habr.vhd फ़ाइल का चयन करते हैं और पदानुक्रम के तहत नीचे से कॉन्फ़िगर लक्ष्य डिवाइस प्रक्रिया की तलाश करते हैं और इसे शुरू करते हैं। हम प्रतीक्षा करते हैं जब परियोजना फर्मवेयर फ़ाइल में अनुवादित होती है, जिसके बाद iMPACT प्रोग्राम विंडो खुलती है, जिसके साथ हम इसे FPGA में सीवे करेंगे।
सीमा स्कैन पर डबल-क्लिक करें, और यदि आपका बोर्ड USB के माध्यम से आपके कंप्यूटर से जुड़ा हुआ है, तो आपको निम्नलिखित कुछ दिखाई देगा:

यदि आपको xc3s500e के लिए फ़र्मवेयर फ़ाइल का चयन करने की पेशकश नहीं की गई थी, तो उचित माइक्रोक्रिकिट पर राइट-क्लिक करें और कॉन्फ़िगरेशन फ़ाइल मेनू आइटम असाइन करें। फ़ाइल चयन विंडो में, नए बनाए गए shim_habr.bit का चयन करें। फिर फिर, xc3s500e पर राइट-क्लिक करें, फिर प्रोग्राम। फर्मवेयर प्रक्रिया शुरू होती है, और फिर प्रोग्राम सफल दिखाई देता है। अगर सब कुछ वैसा ही हो गया, तो आप दुपट्टे को देख सकते हैं =)
भाग 5. एलईडी की चमक में एक सहज बदलाव का प्रोग्रामिंग।
तो, हम देखते हैं कि हमारे पास दो एलईडी हैं - एक उज्ज्वल है, दूसरा मंद है। अब चलो चमक में एक चिकनी बदलाव करने की कोशिश करते हैं। ऐसा करने के लिए, हमें पोरोग को एक स्थिर नहीं, बल्कि एक चर बनाने की जरूरत है, और इसे न्यूनतम से अधिकतम तक आसानी से बदलना होगा।
सिग्नल पोरोग : पूर्णांक सीमा 0 से अधिकतम_काउंट : = 0 ;
थ्रेशोल्ड के परिवर्तन की दर निर्धारित करने के लिए, हमें फिर से घड़ी की आवृत्ति को विभाजित करने और एक छोटा प्राप्त करने की आवश्यकता है। उदाहरण के लिए, हम चाहते हैं कि दहलीज 1 हर 1/600 सेकंड से बढ़े। एक काउंटर बनाएं:
निरंतर max_count_div : पूर्णांक : = clk_freq / 600 ;
संकेत count_div : पूर्णांक सीमा 0 से max_count_div : = 0 ;
और अगले "टिक" के समय प्रोसेस (क्लक) में जोड़ें अगर आरोह_गेज (क्लक) तो एक और शर्त:
अगर count_div = max_count_div तो
count_div <= 0 ;
- यहाँ आवृत्ति 600 में विभाजित है।
अन्यथा
count_div <= count_div + 1 ;
अंत यदि ;
अब हमें उस स्थान पर लिखने की आवश्यकता है जहां आवृत्ति 600 से विभाजित होती है, थ्रेसहोल्ड को 1 से बढ़ाएं और 0 पर रीसेट करें यदि मूल्य एक साथ है:
अगर पोरोग = मैक्स_काउंट तो
porog <= 0 ;
अन्यथा
porog <= porog + 1 ;
अंत यदि ;
नतीजतन, समग्र तस्वीर निम्नानुसार दिखाई देगी:
वास्तुकला shim_habr का व्यवहार है
निरंतर clk_freq : पूर्णांक : = 50 _000_000 ; - क्वार्ट्ज आवृत्ति
निरंतर shim_freq : पूर्णांक : = 10 _000 ; - PWM आवृत्ति
निरंतर max_count : पूर्णांक : = clk_freq / shim_freq ; - PWM क्षमता
संकेत गणना : पूर्णांक सीमा 0 से अधिकतम_कर : = 0 ; - आवृत्ति विभक्त काउंटर
सिग्नल पोरोग : पूर्णांक सीमा 0 से अधिकतम_काउंट : = 0 ; - तार्किक इकाई की पल्स चौड़ाई
निरंतर max_count_div : पूर्णांक : = clk_freq / 600 ;
संकेत count_div : पूर्णांक सीमा 0 से max_count_div : = 0 ;
शुरू करना
प्रक्रिया ( clk )
शुरू करना
अगर उठ रहा है तो ( clk ) तब
अगर गिनती = max_count तो
गिनती <= 0 ;
अन्यथा
गिनती <= गिनती + 1 ;
अंत यदि ;
अगर count_div = max_count_div तो
count_div <= 0 ;
अगर पोरोग = मैक्स_काउंट तो
porog <= 0 ;
अन्यथा
porog <= porog + 1 ;
अंत यदि ;
अन्यथा
count_div <= count_div + 1 ;
अंत यदि ;
अंत यदि ;
अंतिम प्रक्रिया ;
led1 <= ' 1 ' जब गिनती < porog और ' 0 ' ;
led2 <= ' 1 ' ;
अंत व्यवहार ;
हम प्रसारण करते हैं, हम सिलाई करते हैं, हम सफलता में आनन्दित होते हैं। =) आप सोच सकते हैं कि अधिकांश समय एलईडी उज्ज्वल रूप से चमकती है, और यह चक्र की शुरुआत में ही मंद है। मैंने पहले ही
रंग संगीत पर अपने पिछले लेख में इस आशय के बारे में लिखा था। तथ्य यह है कि चमक थ्रेशोल्ड पर रैखिक रूप से नहीं, बल्कि तार्किक रूप से निर्भर करती है। उदाहरण के लिए, 1024 बिट्स के पीडब्लूएम का उपयोग करके न्यूनतम से अधिकतम तक सुचारू रूप से बदलने के लिए चमक के लिए, क्रमिक रूप से पोरोग चर के निम्न मूल्यों को लेना आवश्यक है: 0, 16, 32, 64, 128, 256, 512, 512, 1024।
घर का पाठ।
जैसा कि आप देख सकते हैं, एलईडी धीरे-धीरे चमक हासिल करता है, और जैसे ही इसे डायल किया जाता है, यह तुरंत 0 पर रीसेट हो जाता है (वास्तव में, उन्होंने लिखा और मिल गया)। एक कसरत के रूप में, आप चमक का एक सहज सेट बनाने की कोशिश कर सकते हैं, और अधिकतम शुरुआत तक पहुंचने पर इसे आसानी से शून्य तक कम कर सकते हैं। जो लोग आसानी से इस कार्य का सामना कर सकते हैं, वे आठ उपलब्ध एल ई डी की "रनिंग लाइट" बनाने की कोशिश कर सकते हैं: पहला डायोड रोशनी करता है और बाहर निकलता है, फिर दूसरा, आदि। यदि यह काम नहीं करता है, लेकिन यह दिलचस्प है, तो पूछें - मैं जवाब देने और समझाने की कोशिश करूंगा।
निष्कर्ष।
इसलिए, हमने एलईडी में PWM के अनुप्रयोग में महारत हासिल की है और FPGA का उपयोग करके एलईडी की चमक को समायोजित करना सीखा है। इंजन की गति, कॉइल के चुंबकीय बल आदि को नियंत्रित करने के लिए उसी विधि का उपयोग किया जा सकता है।
मैं FPGAs में महारत हासिल करने के लिए आप सभी सफलता की कामना करता हूं!
पुनश्च: मुझे क्षमा करें, मैं काम पर इस लेख के लिए परियोजना के स्रोत को भूल गया ... जैसे ही मैं इसे वहां से उठाऊंगा (कुछ भी नहीं बस घर पर स्थापित किया गया है) पोस्ट करूँगा। हालांकि, उसे वास्तव में यहां ज़रूरत नहीं है, सब कुछ हो सकता है (और अधिमानतः - आपको ज़रूरत है!) इसे खरोंच से खुद करने के लिए।
UPD:
संशोधित स्रोत ।