मैं Arduino के साथ टाइमर की बाधा कैसे बनाऊं?


9

मैं Arduino के साथ एक समय विलंब व्यवधान बनाने का प्रयास कर रहा हूं। मैं इंटरप्ट () फ़ंक्शन का उपयोग करना चाहूंगा, क्योंकि यह एक आंतरिक व्यवधान है।

उदाहरण: मान लीजिए कि, मैं बीच-बीच में केवल एक पलक झपकना चाहता हूं, जिसमें केवल व्यवधान का समय है।

नमूना कोड है, लेकिन यह बाहरी अवरोधों (संलग्नक) () का उपयोग करता है। मैं आंतरिक व्यवधानों का उपयोग करना चाहता हूं।


2
मुझे लगता है कि कर्टुक ने जो बिंदु दिखाया वह यह है कि संलग्नक एक अमूर्त चीज है, आप किसी भी बाहरी घटक को संलग्न नहीं कर रहे हैं :)
clabacchio

यह लेख आपकी मदद कर सकता है। engblaze.com/…
सेठ आर्चर ब्राउन

जवाबों:


10

नूह स्टाल के ब्लॉग में टिमर 2 के साथ एक एलईडी ब्लिंक करने का एक उदाहरण है । उस और डेटा शीट के साथ, आपको इसे उपयोग करने में सक्षम करने के लिए जो भी आप चाहते हैं - यानी, वह रुकावट जिसका सामान्य कार्य आप को छोड़ना या संशोधित करने के लिए तैयार कर सकते हैं को अनुकूलित करने में सक्षम होना चाहिए। Timer2 आमतौर पर कुछ PWM कार्यों के लिए उपयोग किया जाता है।

उसका उदाहरण ATmega2560 का हवाला देता है; मैं पुष्टि कर सकता हूं कि यह ATmega328p के साथ भी काम करता है। अधिक उपयोगी Arduino इंटरप्ट उदाहरण के लिए उसकी साइट के आसपास देखें।

संपादित करें:

यहाँ मेरा थोड़ा संपादित किया गया है - ज्यादातर टिप्पणियों में - नूह के कोड का संस्करण। Arduino setup () फ़ंक्शन से Timer2init () फ़ंक्शन को कॉल करने के बाद आप किसी भी संबंधित डेटा-संरचना या हार्डवेयर को इनिशियलाइज़ करते हैं, क्योंकि टाइमिंग - और व्यवधान - एक बार शुरू हो जाएगा।

एफ / एक्स, मैंने इसका उपयोग 3 अंकों के 7-सेगमेंट के डिस्प्ले को मल्टीप्लेक्स करने के लिए किया था ताकि मैं टाइमर को इनिशियलाइज़ करने से पहले, मैंने डिस्प्ले I / O रजिस्टर को इनिशियलाइज़ किया और डिस्प्ले डेटा को उस स्थान पर खाली कर दिया जहाँ ISR इसके लिए दिखेगा।

डेटा-शीट से कुछ उपयोगी टाइमिंग डेटा की टिप्पणियों में एक तालिका है और एक अन्य टाइमिंग स्कीम को सेट करने के संदर्भ के लिए मेरी अपनी गणना है।

ISR () मैक्रो एक सामान्य फ़ंक्शन के प्रवेश और निकास के बजाय ISR के लिए इंटरप्ट एंट्री और एग्जिट-कोड बनाने का ध्यान रखता है, और इसे उचित इंटरप्ट वेक्टर से लिंक करता है। उस फ़ंक्शन का बाकी हिस्सा 1) प्रत्येक रुकावट पर चलाया जाने वाला कोड है, और 2) अगले अवरोध के लिए टाइमर को रीसेट करने के लिए कोड कोड।

जैसा कि लिखा गया है, यह एक .pde या .ino स्केच (या एक .cpp फ़ाइल में छोड़ना चाहिए, यदि आप ग्रहण, f / ex) का उपयोग करते हैं। स्केच को #define LEDPIN, और सेटअप () को Timer2init () कॉल करने की आवश्यकता है। लूप फ़ंक्शन खाली हो सकता है या नहीं; एलईडी को डाउनलोड पर चमकना शुरू करना चाहिए (अच्छी तरह से, शाब्दिक रूप से, टिमरिनिट () कहा जाता है)।

/*
 * From sample interrupt code published by Noah Stahl on his blog, at:
 * http://arduinomega.blogspot.com/p/arduino-code.html
 * 
 */


/*** FUNC

Name:           Timer2init

Function:       Init timer 2 to interrupt periodically. Call this from 
                the Arduino setup() function.

Description:    The pre-scaler and the timer count divide the timer-counter
                clock frequency to give a timer overflow interrupt rate:

                Interrupt rate =  16MHz / (prescaler * (255 - TCNT2))

        TCCR2B[b2:0]   Prescaler    Freq [KHz], Period [usec] after prescale
          0x0            (TC stopped)     0         0
          0x1                1        16000.        0.0625
          0x2                8         2000.        0.500
          0x3               32          500.        2.000
          0x4               64          250.        4.000
          0x5              128          125.        8.000
          0x6              256           62.5      16.000
          0x7             1024           15.625    64.000


Parameters: void

Returns:    void

FUNC ***/

void Timer2init() {

    // Setup Timer2 overflow to fire every 8ms (125Hz)
    //   period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
    //                  (1/16000000)  * 1024 * (255-130) = .008 sec


    TCCR2B = 0x00;        // Disable Timer2 while we set it up

    TCNT2  = 130;         // Reset Timer Count  (255-130) = execute ev 125-th T/C clock
    TIFR2  = 0x00;        // Timer2 INT Flag Reg: Clear Timer Overflow Flag
    TIMSK2 = 0x01;        // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
    TCCR2A = 0x00;        // Timer2 Control Reg A: Wave Gen Mode normal
    TCCR2B = 0x07;        // Timer2 Control Reg B: Timer Prescaler set to 1024
}



/*** FUNC

Name:       Timer2 ISR

Function:   Handles the Timer2-overflow interrupt

Description:    Maintains the 7-segment display

Parameters: void

Returns:    void

FUNC ***/

ISR(TIMER2_OVF_vect) {
    static unsigned int led_state = 0; // LED state

    led_state = !led_state;         // toggles the LED state
    digitalWrite(TOGGLE_PIN, led_state);

    TCNT2 = 130;     // reset timer ct to 130 out of 255
    TIFR2 = 0x00;    // timer2 int flag reg: clear timer overflow flag
};

(@Kortuk: आप जिस टिप्पणी का उल्लेख करते हैं, वह यहां कई टिप्पणीकारों का मेरा अवलोकन था और व्यक्तिगत रूप से आपका उद्देश्य नहीं था और यह अनावश्यक था। मैं माफी मांगता हूं और मैंने इसे हटा दिया है।) मैंने अपने सुझाव पर विस्तार किया जैसा कि आपने सुझाव दिया था और मुझे आशा है कि मुझे उम्मीद है। अब न केवल प्रदर्शनकारी, बल्कि शिक्षाप्रद भी। इसमें मेरे स्वयं के उपयोग के लिए कोड में लिखी गई टिप्पणियां शामिल हैं (मतलब: यदि मैं उन्हें अब से 6 महीने बाद समझ सकता हूं, तो कोई और भी कर सकता है), साथ ही कुछ "कैसे उपयोग करें" निर्देशों में निर्देश जवाब। आपके सुझाव के लिए धन्यवाद।
JRobert

ध्यान दें कि टाइमर और टाइमर 1 (atmega328 के साथ कम से कम) के लिए 32 और 128 के प्रीस्केल्स उपलब्ध नहीं हैं।
तुपुला

यह जानना अच्छा है - धन्यवाद। मैं टिमर 2 (अब तक) के लिए इसका उपयोग करता हूं और यह मूल रूप से एक ड्रॉप-इन है।
JRobert

5

AttachInterrupt () समारोह वास्तव में एक पिन पर एक बाहरी राज्य परिवर्तन करने के लिए एक बाधा संलग्न है, यह किसी भी अन्य विकल्प नहीं है।

पर एक ही पृष्ठ मोड विकल्प के रूप में सूचीबद्ध हैं:

मोड परिभाषित करता है कि कब बाधा को ट्रिगर किया जाना चाहिए। चार प्रतियोगियों को मान्य मान के रूप में पूर्वनिर्धारित किया गया है:

  • कम , जब भी पिन कम है बाधा को गति प्रदान करने
  • जब भी पिन मूल्य बदलता है, तो व्यवधान को ट्रिगर करने के लिए बदलें
  • जब पिन कम से उच्च तक जाता है, तो ट्रिगर करने के लिए RISING
  • जब पिन हाई से लो हो जाता है, तब के लिए फीलिंग

बुरी खबर का वाहक होने के लिए क्षमा करें, यह पहली चीजों में से एक है जिसे मैंने भी देखा था।


मुझे लगता है कि वह इसका मतलब है कि वह किसी बाहरी उपकरण के बजाय, एक आंतरिक टाइमर का उपयोग करना चाहते हैं ... लेकिन मैं Arduino बहुत अच्छी तरह से पता नहीं है, तो मैं नहीं कह सकता है, तो यह संभव है
clabacchio

@clabacchio, मैं कह रहा हूं कि बाहरी ट्रिगर का उपयोग करने का एकमात्र विकल्प आंतरिक टाइमर फ़ंक्शन नहीं है।
कोरटुक

आह, अच्छा :) लेकिन कम से कम Arduino बोर्डों के पास कोई समय है?
clabacchio

हां, यह है कि वे देरी जैसी चीजों को कैसे पूरा करते हैं।
कोर्तुक

1
@ icarus74 ATMega328 में वास्तव में 3 टाइमर हैं (एक 16b है और दो 8b हैं) लेकिन इन सभी का उपयोग Arduino द्वारा किया जाता है। एक का उपयोग देरी () और मिलिस () के लिए किया जाता है और तीनों का उपयोग पीडब्लूएम के लिए किया जाता है (आप फंक्शन 'इनिट में अधिक जानकारी पा सकते हैं'), Arduino IDE में फाइल 'wiring.c')।
वास्को

2

पीडब्लूएम का यह लेख Arduino टाइमर के उपयोग के बारे में आपके बहुत सारे संदेह को स्पष्ट करेगा। Arduino पर दो 8-बिट टाइमर और एक 16-बिट टाइमर हैं। ISR फंक्शन को हुक करने के लिए सीधे तौर पर कोई उच्च-स्तरीय API नहीं है, जिसे Arduino SDK (यानी एक मानक लाइब्रेरी के रूप में) के साथ शिप किया जाता है, लेकिन विशेष-फंक्शन-रजिस्टरों और बिट-अरिथेटिक / को सेट करने की कुछ हद तक कम विधि उन पर कार्रवाई। हालांकि एक उपयोगकर्ता योगदान पुस्तकालय है जिसे टाइमर एक कहा जाता है ।


वास्तव में कई अलग-अलग टाइमर संयोजन संभव हैं, जिसके आधार पर Arduino को संदर्भित किया जा रहा है। उत्तर भ्रामक है।
कदाचित तो

@SeeminglySo, देखभाल करने के लिए विस्तृत? यदि आप Arduino हार्डवेयर के बारे में बात कर रहे हैं, तो ध्यान दें कि उत्तर प्रश्न के संदर्भ में है और प्रश्न पूछने के समय का भी।
icarus74

Arduino मेगा (ATmega1280 आधारित) 26 मार्च 2009 को जारी किया गया था, और मेगा 2560 (ATmega2560) 24 सितंबर 2010 को जारी किया गया था, इस प्रश्न के पूछे जाने से पहले दोनों। दोनों माइक्रोकंट्रोलर्स के उत्तर में निर्दिष्ट 2x 8 बिट और 1x 16 बिट टाइमर / काउंटर से अधिक है।
कदाचित तो

अब तक मैंने जो सबसे अधिक बातचीत की है, उसमें अरुमिनो का एक अस्पष्ट संदर्भ है, जिसका अर्थ है ड्यूमिलानोव या यूनो की तरह यानी 328 श्रृंखला आधारित बोर्ड। अन्य बोर्ड हमेशा स्पष्ट रूप से यूपी श्रृंखला संख्या द्वारा योग्य हैं। या मेगा, नैनो, माइक्रो आदि किसी भी तरह, मैं विनम्रतापूर्वक सुधार को स्वीकार करूंगा। इस संदर्भ में, एक स्पष्टीकरण बेहतर है।
इकारस 74४

1

Arduino ATMega328 में सभी तीन टाइमर का उपयोग कर रहा है। Timer1(१६ बिट्स) का उपयोग ५ और ६.६ पर पीडब्लूएम आउटपुट जैसे कार्यों के लिए किया जाता है delay()और millis()अन्य दो समय - Timer0और Timer2३, ९, १०, ११, ११ पर पीडब्लूएम आउटपुट के लिए उपयोग किया जाता है।

तो, टाइमर में व्यवधान के लिए कोई Arduino फ़ंक्शन नहीं है। लेकिन एक रास्ता है। टाइमर अवरोध को सक्षम करने के लिए आप इस कोड का उपयोग कर सकते हैं Timer2:

ISR(TIMER2_OVF_vect) {
  // Interrupt routine.
}

void setup() {
  // Enable Timer2 interrupt.
  TIMSK2 = (0<<OCIE2A) | (1<<TOIE2);
}

void loop() {
  // Your main loop.
}

मैंने यह कोड बिना परीक्षण के लिखा था, इसलिए यह संभव है कि मैंने कोई गलती की हो। उस स्थिति में, डेटाशीट, p.156 की जाँच करें ।

यदि आप टाइमर फ्रीक्वेंसी (प्रीस्कूलर) बदलना चाहते हैं, तो बस रजिस्टर बदलें TCCR2A। अधिक जानकारी के लिए डेटाशीट पेज 153 पर गौर करें। लेकिन अगर आप टाइमर की आवृत्ति बदलते हैं, तो आप दो आउटपुट पिन पर PWM सिग्नल की आवृत्ति भी बदलते हैं!


ATmega328 पर AFAIK Timer0और Timer28 बिट हैं और केवल Timer116 बिट है।
तुपुला

नहीं, यह सही नहीं है। यह Timer0 है, न कि Timer1, जो देरी () और मिलिस () के लिए और पिन 5 पर पीडब्लूएम आउटपुट के लिए उपयोग किया जाता है और 6. टाइमर 0 एक 8-बिट टाइमर है। उदाहरण के लिए देखें Arduino टाइमर और व्यवधान
पीटर मोर्टेंसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.