मुझे लगता है कि वैक्टर और पिन का नामकरण ओवरलैप भ्रमित कर रहा है
यह है!
एक रुकावट वेक्टर के लिए 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
...
}
तो अगर pins
0x01 आपको पता है कि यह 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 */
}
}