- जब हमारे पास देरी () क्यों है?
- तस्वीर माइक्रोकंट्रोलर टाइमर:
- प्रोग्रामिंग और कार्य विवरण:
- सर्किट आरेख और प्रोटीन सिमुलेशन:
यह हमारी PIC ट्यूटोरियल श्रृंखला में पांचवां ट्यूटोरियल होगा, जो PIC16F877A में टाइमर सीखने और उपयोग करने में आपकी सहायता करेगा । हमारे पिछले ट्यूटोरियल में, हमने PIC और MPLABX IDE के परिचय के साथ शुरुआत की थी, तब हमने PIC का उपयोग करके LED को ब्लिंक करने के लिए अपना पहला PIC प्रोग्राम लिखा और फिर PIC Microcontroller में देरी फ़ंक्शन का उपयोग करके एक एलईडी ब्लिंकिंग अनुक्रम बनाया। अब हम उसी LED ब्लिंकिंग सीक्वेंस का उपयोग करते हैं जिसका उपयोग हमने पिछले ट्यूटोरियल हार्डवेयर में किया है और इसके साथ हम सीखेंगे कि अपने PIC MCU में टाइमर का उपयोग कैसे करें । हमने इस ट्यूटोरियल के लिए एलईडी बोर्ड में सिर्फ एक और बटन जोड़ा है। अधिक जानने के लिए ट्यूटोरियल के माध्यम से जाएं।
एक एम्बेडेड प्रोग्रामर के लिए टाइमर महत्वपूर्ण कार्यक्षेत्रों में से एक है। हर एप्लिकेशन जिसे हम डिज़ाइन करते हैं, किसी न किसी तरह एक टाइमिंग एप्लिकेशन को शामिल करते हैं, जैसे समय के निर्दिष्ट अंतराल के बाद कुछ को चालू या बंद करना। ठीक है, लेकिन जब हमें पहले से ही मैक्रोज़ (__delay_ms ()) एक ही काम करने में देरी हो रही है तो हमें टाइमर की आवश्यकता क्यों है !!
जब हमारे पास देरी () क्यों है?
देरी मैक्रो को "डंप" देरी कहा जाता है। क्योंकि देरी समारोह के निष्पादन के दौरान MCU बस देरी पैदा करके डंप बैठता है । इस प्रक्रिया के दौरान MCU अपने ADC मानों को नहीं सुन सकता है या अपने रजिस्टरों से कुछ भी नहीं पढ़ सकता है। इसलिए, एलईडी ब्लिंकिंग जैसे अनुप्रयोगों के लिए विलंब कार्यों का उपयोग करना उचित नहीं है जहां समय की देरी सटीक या लंबी नहीं होनी चाहिए।
विलंब मैक्रोज़ में निम्न लघु चित्रण भी हैं,
- विलंब का मूल्य विलंब मैक्रो के लिए एक स्थिर होना चाहिए; इसे प्रोग्राम एक्जीक्यूशन के दौरान नहीं बदला जा सकता है। इसलिए यह प्रोग्रामर परिभाषित है।
- टाइमर का उपयोग करने की तुलना में देरी सटीक नहीं होगी।
- देरी के बड़े मूल्यों को मैक्रोज़ का उपयोग करके नहीं बनाया जा सकता है, उदाहरण के लिए विलंब मैक्रोज़ द्वारा आधे घंटे की देरी का निर्माण नहीं किया जा सकता है। अधिकतम विलंब जिसका उपयोग किया जा सकता है, वह क्रिस्टल थरथरानवाला पर आधारित होता है।
तस्वीर माइक्रोकंट्रोलर टाइमर:
शारीरिक रूप से, टाइमर एक रजिस्टर है जिसका मूल्य लगातार 255 तक बढ़ रहा है, और फिर यह फिर से शुरू होता है: 0, 1, 2, 3, 4… 255… 0, 1, 2, 3…।..आदि।
PIC16F877A PIC MCU तीन टाइमर मॉड्यूल है । वे टाइमर 0, टिमर 1 और टिमर 2 के नाम हैं। टाइमर 0 और टाइमर 2 8-बिट टाइमर हैं और टाइमर 1 16-बिट टाइमर है। इस ट्यूटोरियल में हम अपने एप्लिकेशन के लिए टाइमर 0 का उपयोग करेंगे। एक बार जब हम टाइमर 0 को समझ लेते हैं तो टाइमर 1 और टाइमर 2 पर भी काम करना आसान हो जाएगा।
Timer0 मॉड्यूल टाइमर / काउंटर में निम्नलिखित विशेषताएं हैं:
- 8-बिट टाइमर / काउंटर
- पठनीय और लिखने योग्य
- 8-बिट सॉफ़्टवेयर प्रोग्रामेबल प्रीस्कूलर
- आंतरिक या बाहरी घड़ी का चयन करें
- FFh से 00h पर अतिप्रवाह पर रुकावट
- बाहरी घड़ी के लिए किनारे का चयन करें
टाइमर का उपयोग करना शुरू करने के लिए हमें कुछ फैंसी शब्दों जैसे 8-बिट / 16-बिट टाइमर, प्रिस्कलर, टाइमर इंटरप्ट और फोक्स को समझना चाहिए । अब, आइए देखें कि प्रत्येक का वास्तव में क्या मतलब है। जैसा कि पहले कहा गया था कि हमारे PIC MCU में दोनों 8-बिट और 16-बिट टाइमर हैं, उनके बीच मुख्य अंतर यह है कि 16-बिट टाइमर में बेहतर समाधान है कि 8-बिट टाइमर।
प्रीस्कूलर एक माइक्रोकंट्रोलर के हिस्से के लिए एक नाम है जो टाइमर की स्थिति को बढ़ाने वाले तर्क तक पहुंचने से पहले थरथरानवाला घड़ी को विभाजित करता है। प्रिस्क्रेलर आईडी की सीमा 1 से 256 तक है और प्रिस्लेकर के मूल्य को ऑप्शन रजिस्टर का उपयोग करके सेट किया जा सकता है (वही जिसे हमने प्रतिरोधों को खींचने के लिए इस्तेमाल किया था)। उदाहरण के लिए, यदि प्रीस्कूलर का मूल्य 64 है, तो प्रत्येक 64 वें पल्स के लिए टाइमर 1 से बढ़ जाएगा।
टाइमर में वृद्धि के रूप में और जब यह 255 के अपने अधिकतम मूल्य तक पहुंच जाता है, तो यह एक रुकावट को ट्रिगर करेगा और खुद को फिर से 0 पर फिर से शुरू करेगा। इस रुकावट को टाइमर इंटरप्ट कहा जाता है। यह रुकावट MCU को सूचित करता है कि इस विशेष समय में चूक हुई है।
Fosc थरथरानवाला की आवृत्ति के लिए खड़ा है, यह प्रयोग किया जाता क्रिस्टल की आवृत्ति है। टाइमर रजिस्टर के लिए लिया गया समय प्रीस्कूलर के मूल्य और फोस के मूल्य पर निर्भर करता है।
प्रोग्रामिंग और कार्य विवरण:
इस ट्यूटोरियल में हम दो बटन को दो इनपुट के रूप में और 8 एलईडी को 8 आउटपुट के रूप में सेट करेंगे। पहला बटन समय देरी (हर पुश के लिए 500ms) को सेट करने के लिए उपयोग किया जाएगा और दूसरा बटन टाइमर अनुक्रम ब्लिंकिंग शुरू करने के लिए उपयोग किया जाएगा। उदाहरण के लिए, यदि पहला बटन तीन बार दबाया जाता है (500 * 3 = 1500ms) देरी 1.5sec के लिए सेट किया जाएगा और जब बटन दो दबाया जाता है तो प्रत्येक एलईडी पूर्वनिर्धारित समय देरी के साथ चालू और बंद हो जाएगा। इस ट्यूटोरियल के अंत में प्रदर्शन वीडियो देखें ।
अब, इन मूल बातों को ध्यान में रखते हुए, हम कोड सेक्शन में अंत में दिए गए अपने प्रोग्राम को देखें ।
कार्यक्रम नहीं मिला तो ठीक है, लेकिन अगर आपने किया है !! अपने आप को एक कुकी दें और अपने आउटपुट का आनंद लेने के लिए प्रोग्राम को डंप करें। दूसरों के लिए मैं कार्यक्रम को सार्थक भागों में तोड़ूंगा और आपको बताऊंगा कि प्रत्येक ब्लॉक में क्या हो रहा है।
हमेशा की तरह कोड की पहली कुछ पंक्तियां कॉन्फ़िगरेशन सेटिंग्स और हेडर फाइलें हैं, मैं इसे समझाने नहीं जा रहा हूं क्योंकि मैंने पहले ही अपने पिछले ट्यूटोरियल में किया है।
अगला, हम सभी लाइनों को छोड़ दें और सीधे शून्य मुख्य फ़ंक्शन में कूदें, जिसके अंदर हम टाइमर 0 के लिए PORT कॉन्फ़िगरेशन है।
शून्य मुख्य () {/ ***** टाइमर के लिए पोर्ट कॉन्फ़िगरेशन ****** / OPTION_REG = 0b00000101; // Timer0 बाहरी फ्रीक के साथ और 64 प्रीस्कूलर के रूप में // इसके अलावा PULL UPs TMR0 = 100 को सक्षम करता है; // 0.0019968 के लिए समय मान लोड करें; delayValue 0-256 केवल TMR0IE = 1 के बीच हो सकता है; // PIE1 रजिस्टर GIE = 1 में टाइमर इंटरप्ट बिट सक्षम करें; // वैश्विक रुकावट PEIE = 1 सक्षम करें; // पेरिफेरल इंटरप्ट को सक्षम करें / *********** ______ *********** /
इसे समझने के लिए हमें अपने PIC डेटाशीट में विकल्प रजिस्टर को देखना होगा।
जैसा कि पिछले ट्यूटोरियल में चर्चा की गई थी कि 7 का उपयोग PORTB के लिए कमजोर पिंड को रोकने के लिए किया जाता है। उपरोक्त आंकड़े को देखें, एमसीयू को निर्देश देने के लिए बिट 3 को 0 बनाया गया है कि जो पूर्व निर्धारित किया जा रहा है उसका उपयोग टाइमर के लिए किया जाना चाहिए न कि वॉचडॉगिमर (डब्लूडीटी) के लिए। टाइमर मोड का चयन बिट 5 T0CS को साफ़ करके किया जाता है
(OPTION_REG <5>)
अब, बिट्स 2-0 का उपयोग टाइमर के लिए प्रीस्कूलर मान सेट करने के लिए किया जाता है। जैसा कि 64 का प्रीस्कूलर मान सेट करने के लिए ऊपर दी गई तालिका में दिखाया गया है, बिट्स को 101 के रूप में सेट किया जाना चाहिए।
अगला, हम टाइमर 0 से जुड़े रजिस्टरों पर गौर करते हैं
टाइमर एक बार सेट करने के बाद इंक्रीमेंट करना शुरू कर देगा और 256 के मान तक पहुंचने के बाद ओवरफ्लो हो जाएगा, जिससे कि इस बिंदु के दौरान टाइमर की बाधा को सक्षम किया जा सके, रजिस्टर TMR0IE को उच्च सेट किया जाना है। चूँकि टाइमर 0 खुद एक पेरिफेरल है इसलिए हमें PEIE = 1 बनाकर पेरिफेरल इंटरप्ट को सक्षम करना होगा । अंत में हमें ग्लोबल इंटरप्ट को सक्षम करना होगा ताकि MCU को किसी भी ऑपरेशन के दौरान इंटरप्ट के बारे में सूचित किया जा सके, यह GIE = 1 बनाकर किया जाता है ।
विलंब = ((256-REG_val) * (प्रीस्कूल * 4)) / फोक
उपरोक्त सूत्र का उपयोग विलंब के मूल्य की गणना करने के लिए किया जाता है।
कहाँ पे
REG_val = 100;
प्रीस्कूल = 64
फोक = 20000000
यह गणना पर देता है, विलंब = 0.0019968s
लाइनों का अगला सेट I / O पोर्ट सेट करना है।
I / O ****** / TRISB0 = 1 के लिए / ***** पोर्ट कॉन्फ़िगरेशन; // MCU को निर्देश दें कि PORTB पिन 0 को बटन 1 के इनपुट के रूप में प्रयोग किया जाता है। TRISB1 = 1; // MCU को निर्देश दें कि PORTB पिन 1 का उपयोग बटन के लिए इनपुट के रूप में किया जाता है। TRISD = 0x00; // MCU को निर्देश दें कि PORT D पर सभी पिन आउटपुट PORTD = 0x00 हैं; // 0 / *********** ______ *********** / के लिए सभी पिन प्रारंभ करें
यह हमारे पिछले ट्यूटोरियल की तरह ही है क्योंकि हम उसी हार्डवेयर का उपयोग कर रहे हैं। सिवाय इसके कि हमने इनपुट के रूप में एक और बटन जोड़ा है। यह TRISB1 = 1 लाइन द्वारा किया जाता है ।
अगला, लूप रहते हुए अनंत के अंदर हमारे पास कोड के दो ब्लॉक हैं। एक का उपयोग उपयोगकर्ता से टाइमर इनपुट प्राप्त करने के लिए किया जाता है और दूसरा एल ई डी पर देरी के अनुक्रम को निष्पादित करने के लिए किया जाता है। मैंने प्रत्येक पंक्ति के खिलाफ टिप्पणियों का उपयोग करके उन्हें समझाया है।
जबकि (1) {गिनती = 0; // मुख्य लूप में रहते हुए टाइमर न चलाएं। ******* उपयोगकर्ता से देरी का नंबर प्राप्त करें **** ////// अगर (RB0 == 0 && ध्वज == 0) // जब इनपुट {get_scnds + = 1; // get_scnds = get_scnds + http: // इंक्रीमेंट वेरिएबल फ्लैग = 1; } अगर (RB0 == 1) // निरंतर वृद्धि ध्वज को रोकने के लिए = 0; / *********** ______ *********** /
एक चर जिसे get_scnds कहा जाता है, हर बार वृद्धि होती है जब उपयोगकर्ता बटन दबाता है 1. एक ध्वज (सॉफ्टवेयर परिभाषित) चर का उपयोग वृद्धिशील प्रक्रिया को पकड़ने के लिए किया जाता है जब तक कि उपयोगकर्ता बटन से अपनी उंगली नहीं हटाता है।
// ******* विलंब के साथ अनुक्रम **** ////// जबकि (RB1 == 0) {PORTD = 0b00000001 <
बटन दो दबाए जाने पर अगला ब्लॉक एक्शन में आ जाता है। चूंकि उपयोगकर्ता ने पहले ही बटन एक का उपयोग करके आवश्यक समय देरी को परिभाषित किया है और इसे चर get_scnds में सहेजा गया है । हम hscnd नामक वैरिएबल का उपयोग करते हैं, यह वैरिएबल ISR (इंटरप्ट सर्विस रूटीन) द्वारा नियंत्रित होता है।
बाधा सेवा दिनचर्या एक इंटरप्ट है कि हर बार Timer0 अतिप्रवाह है बुलाया जाएगा है। आइए देखें कि अगले ब्लॉक में आईएसआर द्वारा इसे कैसे नियंत्रित किया जा रहा है, जैसे हम प्रत्येक बटन प्रेस पर आधे सेकंड (0.5 एस) द्वारा समय की देरी को बढ़ाना चाहते हैं, फिर हमें हर आधे सेकंड के लिए चर hscnd को बढ़ाना होगा । जैसा कि हमने अपने टाइमर को हर 0.0019968s (~ 2ms) पर ओवर फ्लो करने के लिए प्रोग्राम किया है, इसलिए काउंट करने के लिए आधा सेकंड काउंट वेरिएबल 250 होना चाहिए क्योंकि 250 * 2ms = 0.5 सेकंड। इसलिए जब गिनती 250 (250 * 2ms = 0.5 सेकंड) हो जाती है, तो इसका मतलब है कि इसका आधा दूसरा है इसलिए हम 1 से वृद्धि करते हैं और गिनती को शून्य तक बढ़ाते हैं ।
शून्य अवरोध टाइमर_isr () {अगर (TMR0IF == 1) // टाइमर ओवरफ्लो के कारण टाइमर ध्वज को ट्रिगर किया गया है {TMR0 = 100; // टाइमर मान लोड करें TMR0IF = 0; // क्लियर टाइमर इंटरप्ट फ्लैग काउंट ++; } अगर (गिनती == 250) {hscnd + = 1; // hscnd हर आधे सेकंड की गिनती = 0 के लिए बढ़ेगा; }}
इसलिए हम इस मूल्य का उपयोग करते हैं और इसे अपने hscnd से तुलना करते हैं और हमारे एलईडी को उपयोगकर्ता द्वारा निर्धारित समय के आधार पर शिफ्ट करते हैं। यह भी पिछले ट्यूटोरियल के समान है।
यही कारण है कि हमारे पास हमारे कार्यक्रम को समझा और काम किया है
सर्किट आरेख और प्रोटीन सिमुलेशन:
सामान्य रूप से पहले प्रोटीन का उपयोग करके आउटपुट को सत्यापित करने की सुविधा देता है, मैंने यहां प्रोटीन की योजनाबद्ध फ़ाइलों को जोड़ा है।
हमारे पिछले एलईडी बोर्ड में एक बटन जोड़ें और हमारा हार्डवेयर जाने के लिए तैयार है। यह कुछ इस तरह दिखना चाहिए:
कनेक्शन हो जाने के बाद, कोड अपलोड करें और आउटपुट को सत्यापित करें। यदि आपको कोई समस्या है तो कृपया टिप्पणी अनुभाग का उपयोग करें। यह भी जांच वीडियो नीचे पूरी प्रक्रिया को समझने के लिए।