यह निर्धारित करते हुए कि किस पिन ने PCINTn को बाधित किया है?


9

क्या मैं यह सोचने में सही हूं कि यदि आपके पास एक ही AVR PCINT रुकावट के कारण दो पिन हैं, (जैसे PCINT0 वेक्टर या तो PCINT0 या PCINT1 पिन के कारण - मुझे लगता है कि वैक्टर और पिन के नामकरण ओवरलैप भ्रमित है) जो पिन को निर्धारित करने का एकमात्र तरीका है (एस) के कारण रुकावट प्रत्येक बाधा के बाद उनके राज्य को रिकॉर्ड करने और पीसीएमएसकेएन में सक्षम सभी पिनों के पिछले और वर्तमान मूल्यों की तुलना करने के लिए है?


1
एवीआर का उपयोग करने के बाद मुझे कुछ समय हो गया है, लेकिन मुझे यकीन है कि एक झंडा होना चाहिए जो सही पिन के लिए ट्रिगर हो। व्यवधान आने के बाद यह ध्वज स्पष्ट होना चाहिए, ताकि आपको राज्य संग्रहीत करने की आवश्यकता न हो। तथ्य यह है कि झंडा सेट पर्याप्त है
Gustavo Litovsky

@ gl3829 झंडे पिन के समूह के अनुसार हैं अगर मैं सही ढंग से समझ रहा हूं
टॉम डेविस

जवाबों:


11

मुझे लगता है कि वैक्टर और पिन का नामकरण ओवरलैप भ्रमित कर रहा है

यह है!

एक रुकावट वेक्टर के लिए 8 अलग-अलग बाहरी पिन हैं इसका कारण पीसीबी को लेआउट करना या किसी अन्य पिन फ़ंक्शन के साथ संघर्ष होने पर एक अलग पिन का उपयोग करना आसान बनाना है।

क्या मैं सोचने में सही हूं ... किस पिन (ओं) को निर्धारित करने का एकमात्र तरीका यह है कि प्रत्येक रुकावट के बाद उनके राज्य को रिकॉर्ड किया जाए और पीसीएमएसकेएन में सक्षम सभी पिनों के पिछले और वर्तमान मूल्यों की तुलना करें?

बहुत ज्यादा, आपको केवल PB0 (PCINT0) और PB1 (PCINT1) की परवाह करने देता है। तो पिन परिवर्तन सक्षम मास्क PCMSK0 0x03 पर सेट किया जाएगा।

// External Interrupt Setup
...

volatile u_int8 previousPins = 0; 
volatile u_int8 pins = 0; 

ISR(SIG_PIN_CHANGE0)
{
    previousPins = pins; // Save the previous state so you can tell what changed
    pins = (PINB & 0x03); // set pins to the value of PB0 and PB1
    ...
}

तो अगर pins0x01 आपको पता है कि यह PB0 था ... और अगर आपको यह जानने की जरूरत है कि आपको इसकी तुलना करने के लिए क्या बदलाव की आवश्यकता है previousPins, तो वास्तव में आपने जो सोचा था, उससे बहुत अधिक।

कुछ मामलों में ध्यान रखें, pinsसटीक नहीं हो सकता है यदि पिन में रुकावट के बाद से पहले लेकिन पहले स्थिति में परिवर्तन हो pins = (PINB & 0x03)

एक अन्य विकल्प प्रत्येक वेक्टर से एक पिन के साथ अलग-अलग रुकावट वाले वैक्टर का उपयोग करना होगा ताकि आप जान सकें कि कौन सा बदल गया है। फिर, यह भी कुछ मुद्दों पर, बाधा प्राथमिकता की तरह है और एक बार सीपीयू ISR प्रवेश करती है, वैश्विक बिट सक्षम व्यवधान I-bitमें SREGहै, तो साफ हो जाएगा कि अन्य सभी बीच में आता है अक्षम हैं आप बाधा के अंदर यह सेट कर सकते हैं, हालांकि अगर आप चाहते हैं, कि होगा एक नेस्टेड रुकावट हो।

अधिक जानकारी के लिए, MegaAVR डिवाइसेस के लिए बाहरी व्यवधान का उपयोग करते हुए Atmel के ऐप नोट पर एक नज़र डालें

अपडेट करें

यहां एक पूर्ण कोड उदाहरण है जो मैंने अभी यहां पाया है

#include <avr/io.h>
#include <stdint.h>            // has to be added to use uint8_t
#include <avr/interrupt.h>    // Needed to use interrupts
volatile uint8_t portbhistory = 0xFF;     // default is high because the pull-up

int main(void)
{
    DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2)); // Clear the PB0, PB1, PB2 pin
    // PB0,PB1,PB2 (PCINT0, PCINT1, PCINT2 pin) are now inputs

    PORTB |= ((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2)); // turn On the Pull-up
    // PB0, PB1 and PB2 are now inputs with pull-up enabled

    PCICR |= (1 << PCIE0);     // set PCIE0 to enable PCMSK0 scan
    PCMSK0 |= (1 << PCINT0);   // set PCINT0 to trigger an interrupt on state change 

    sei();                     // turn on interrupts

    while(1)
    {
    /*main program loop here */
    }
}

ISR (PCINT0_vect)
{
    uint8_t changedbits;

    changedbits = PINB ^ portbhistory;
    portbhistory = PINB;

    if(changedbits & (1 << PB0))
    {
    /* PCINT0 changed */
    }

    if(changedbits & (1 << PB1))
    {
    /* PCINT1 changed */
    }

    if(changedbits & (1 << PB2))
    {
    /* PCINT2 changed */
    }
}

वैक्टर में तीन पिन चेंज इंटरप्ट होते हैं, जिसमें वेक्टर्स PCINT [0-2] होते हैं, लेकिन इनमें से प्रत्येक पिन के एक सेट से चालू होता है। मेरा प्रश्न इस बात को लेकर है कि उस सेट में किस पिन के अंतर को कैसे बाधित किया जाए।
टॉम डेविस

@TomDavies आप सही हैं, धन्यवाद, मैंने अपना उत्तर बदल दिया है लेकिन यह वही है जो आपने सोचा था। और मैंने डेटाशीट के माध्यम से पढ़ा, यह इंगित करने के लिए कोई ध्वज नहीं है कि पिन क्या बदल गया।
गैरेट फोगरेली

@ गैरेट: क्या आप जानते हैं कि आपके मूल उदाहरण में कोई भी आसानी से यह निर्धारित कर सकता है कि क्या यह गिरने या बढ़ती बढ़त थी जिसने रुकावट पैदा की थी? (ठीक है, जब तक कि दोनों पिन एक ही क्षण में बदल नहीं गए ... लेकिन इस मामले में केवल काला जादू मदद करता है) (पिछले_पिन> पिन): गिरने वाला किनारा (पिछले पिन <पिन): बढ़ती बढ़त शायद यह ऊपर उल्लेख के लायक है।

@TomDavies PINB में PCINT0-7, PINC में PCINT8-15 आदि शामिल हैं
EkriirkE

0

नए ATTINY सीरीज़ INTFLAGSरजिस्टर पर आपको बताएंगे कि पोर्ट बिट ने क्या रुकावट पैदा की है।

यहाँ डेटाशीट का अंश दिया गया है:

बिट्स 7: 0 - INT [7: 0]: इंटरप्ट पिन फ्लैग INT फ्लैग तब सेट होता है जब पिन परिवर्तन / स्थिति पिन के इनपुट सेंस कॉन्फ़िगरेशन से मेल खाती है। ध्वज के बिट स्थान पर '1' लिखने से ध्वज साफ़ हो जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.