क्या माइक्रोकंट्रोलर के विभिन्न पोर्ट के अलग-अलग पिनों को रजिस्टर में मैप किया जा सकता है और रजिस्टर वैल्यू को बदलते समय उनके मूल्यों को बदला जा सकता है?


12

प्रश्न: क्या माइक्रो-कंट्रोलर के विभिन्न पोर्ट के अलग-अलग पिनों को रजिस्टर में मैप किया जा सकता है और रजिस्टर वैल्यू को बदलते समय उनके मूल्यों को बदला जा सकता है?

परिदृश्य: मैंने माइक्रो-कंट्रोलर के प्रत्येक पोर्ट (8-बिट्स) से कुछ पिनों का उपयोग किया है। अब मैं एक ऐसे डिवाइस को इंटरफेस करना चाहता हूं, जिसमें 8-बिट बस की जरूरत हो (मान लीजिए कि D0 से D7 IN SEQUENCE) यह कहना है कि मुझे कंट्रोलर से 8 पिन चाहिए ताकि मैं उन्हें एक-से-एक फैशन से जोड़ सकूं

portx0  -> D0 // x is the name of port followed by bit location on that port
portx1  -> D1
...
portx7  -> D7

लेकिन मेरे पास 8 पिन का एक पूरा पोर्ट नहीं है जिसे मैं इस डिवाइस से जोड़ सकता हूं, बल्कि मेरे पास पोर्ट से कुछ पिन हैं, कुछ पोर्ट से हैं और पोर्ट से कुछ पिन हैं। नया कनेक्शन परिदृश्य क्रमशः (माइक्रो-कंट्रोलर से डिवाइस से कनेक्शन) है

portx0  -> D0
portx1  -> D1
portx2  -> D2
porty4  -> D3
porty5  -> D4
porty6  -> D5
porty7  -> D6
portz1  -> D7

इस हालत में अगर मैं मान कहना चाहता हूं

unsigned char dataReg = 0xFA;

नियंत्रक से अपने डिवाइस पर मुझे व्यक्तिगत रूप से रजिस्टर में मूल्य के अनुसार प्रत्येक पिन को भेजने और सेट करने के लिए मूल्य पर थोड़ा बुद्धिमान संचालन करना होगा। उदाहरण के लिए

portx0 = ((dataReg & 0x01) >> 0 );  // Masking and shifting as bit position
portx1 = ((dataReg & 0x02) >> 1 );
portx2 = ((dataReg & 0x04) >> 2 );
porty4 = ((dataReg & 0x08) >> 3 );
porty5 = ((dataReg & 0x10) >> 4 );
porty6 = ((dataReg & 0x20) >> 5 );
porty7 = ((dataReg & 0x40) >> 6 );
portz1 = ((dataReg & 0x80) >> 7 );

अब, मुख्य प्रश्न पर आते हैं, अलग-अलग बंदरगाहों पर प्रत्येक बिट पर इन व्यक्तिगत गणनाओं से बचने के लिए, क्या एक माइक्रो-कंट्रोलर के अलग-अलग पोर्ट के अलग-अलग पिनों को रजिस्टर में मैप किया जा सकता है और रजिस्टर वैल्यू बदलते समय उनके मूल्यों को बदला जा सकता है?


1
मुझे कुछ समय पहले ऐसा ही विचार आया था। PIC के साथ, यह संभव नहीं है: microchip.com/forums/tm.aspx?high=&m=696277 - मुझे नहीं लगता कि यह किसी भी सूक्ष्म के साथ संभव है, लेकिन आपके डिवाइस को सूचीबद्ध करना सहायक होगा।

जवाबों:


6

ऐसा प्रतीत होता है कि आपका प्रश्न फर्मवेयर में 8 बिट मान के साथ आता है, और पोर्ट पिन के मनमाने संग्रह से पढ़ना और लिखना चाहता है।

ऐसा करने के लिए कोई सीधा हार्डवेयर तरीका नहीं है। आपको दो रूटीन लिखने होंगे, एक 8 बिट वैल्यू पढ़ने के लिए और दूसरा इसे लिखने के लिए। दूसरों ने यूनियनों का उपयोग करने का उल्लेख किया है, लेकिन यह एक बुरा विचार है। यूनियनों के साथ, आपको हर बिट को अलग से निपटाना होगा, और कोड माइक्रो के बिट ऑर्डर पर निर्भर हो जाएगा। यह वैसे भी जाने का तरीका हो सकता है अगर सभी 8 बिट्स पूरी तरह से स्वतंत्र रूप से बिखरे हुए हैं। यदि हां, तो बहुत कम है जो आप कर सकते हैं लेकिन प्रत्येक बिट के लिए विशेष कोड बनाने के लिए।

इसे करने का बेहतर तरीका है, खासकर यदि आप बिट्स को कुछ बंदरगाहों पर भौतिक बंदरगाहों पर समूह में रख सकते हैं, तो मास्किंग, शिफ्टिंग और ओरिंग का उपयोग करना है। उदाहरण के लिए, यदि आंतरिक बाइट के निचले तीन बिट्स पोर्ट के <6-4> बिट्स पर हैं, तो उस पोर्ट वैल्यू को 4 से राइट करें और 7 के साथ उन बिट्स को अपनी अंतिम स्थिति में लाएं। शिफ्ट और मास्क (या मास्क और शिफ्ट) बिट्स को अन्य पोर्ट्स से जगह देते हैं और अंतिम 8 बिट बाइट को इकट्ठा करते हैं और उसमें परिणाम प्राप्त करते हैं।

इस तरह के निम्न स्तर की बिट ट्विगलिंग सी की तुलना में असेंबलर में करना आसान होता है। मैं शायद एक ही कोडांतरक मॉड्यूल में बाइट को पढ़ता और लिखता हूं और सी से इंटरफ़ेस को कॉल करने योग्य बनाता हूं।


6
मेरा उत्तर आपके लिए लगभग समान होगा, सिवाय इसके कि मैं असेंबली का उपयोग नहीं करूंगा; बिट जोड़तोड़ सी में तुच्छ हैं। मुझे लगता है कि यह कंपाइलर के लिए विशिष्ट सी कॉलिंग कन्वेंशन सीखने और लिंकर को चलाने के लिए सिरदर्द (पुनः) के अधिक होगा। कंपाइलर पर वास्तव में निर्भर करता है और यह कितना मुश्किल काम करता है। :-)
akohlsmith

@ और: गंभीरता से? कॉलिंग सम्मेलनों को स्पष्ट रूप से किसी भी कंपाइलर मैनुअल में देखा गया है जहां मैंने देखा है कि विधानसभा कोड के साथ इंटरफ़ेस करने की आवश्यकता हो सकती है। बिट हेरफेर सी में लिखने के लिए "तुच्छ" हो सकता है, लेकिन यह एक ऐसा क्षेत्र है जहां संकलक भयावह कोड का उत्पादन कर सकते हैं। यदि गति या कोड स्थान कोई फर्क नहीं पड़ता है, तो जो भी आपके साथ अधिक आरामदायक है उसका उपयोग करें। मैं कम लेवल बिट ट्विडलिंग के लिए कोडांतरक के साथ अधिक सहज हूं, इसलिए मैं इसका उपयोग करूंगा। यदि यह एक निम्न स्तर की गति-गंभीर दिनचर्या है, तो आपको इसे असेंबलर में करना चाहिए। यह वास्तव में आसान होना चाहिए।
ओलिन लेथ्रोप

1
मैं जो कह रहा हूं, वह यह है कि कुछ के लिए तुच्छ के रूप में बिट हेरफेर के साथ कुछ भी नहीं है जो मैं तब तक करूंगा जब तक कि इसके लिए बहुत अच्छा कारण नहीं था। हम उसकी समानांतर बस की बारीकियों को नहीं जानते हैं लेकिन अधिकांश बसों में स्ट्रोब सिग्नल होते हैं जो सभी बस पिनों के "परमाणु के पास" अपडेट की आवश्यकता को समाप्त करते हैं, इसलिए असेंबली को छोड़ने की संभावना एक अनावश्यक अनुकूलन और एक अनावश्यक जटिलता है (भले ही यह हो straightforwardish)।
akohlsmith

@ और पूछा: यदि आप नहीं जानते कि आप क्या कर रहे हैं तो यह केवल इधर-उधर या जटिल है। मुझे लगता है कि असली समस्या यह है कि कुछ लोग असेंबलर से डरते हैं और इसे अच्छी तरह से नहीं जानते हैं। वह गलती है। यह आपके टूलबॉक्स में एक तैयार उपकरण होना चाहिए। यदि आप इसे अच्छी तरह से नहीं जानते हैं या इसके साथ असहज हैं, तो आप हमेशा यह बताएंगे कि चीजों को किसी अन्य तरीके से कैसे किया जाना चाहिए। कुछ चीजें असेंबलर में आसान होती हैं यदि आप इसे जानते हैं और एचएलएल समान रूप से अच्छी तरह से। ज्यादातर लोगों को नहीं है, लेकिन यह उनके साथ एक समस्या है, कोडांतरक का उपयोग करने के साथ नहीं।
ओलिन लेथ्रोप

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

4

सामान्य तौर पर यह संभव नहीं है। जहाँ तक मुझे पता है, यह तस्वीर के साथ संभव नहीं है।

केवल एक ही माइक्रोकंट्रोलर है जो मैं जानता हूं कि यह कर सकता है, सरू पीएसओसी । यह चिप पर एक उच्च विन्यास प्रणाली है। कई चीजों में से यह आपको करने की अनुमति देता है वस्तुतः अपने स्वयं के रजिस्टर (1-8 बिट्स) को परिभाषित करने और इसे किसी भी पिन से जोड़ने के लिए जिसे आप पसंद करते हैं, या यहां तक ​​कि आंतरिक सर्किट तक।

PSoC वायरिंग

उदाहरण के लिए, यहां मैंने 6-बिट कंट्रोल रजिस्टर बनाया है। 5 बिट्स सीधे पिन में जाते हैं, जबकि 6 वें बिट मैं 7 वें पिन से इनपुट के साथ XOR का उपयोग कर रहा हूं।

PSoC पिंस

चिप पर, मैं इन पिनों को किसी भी उपलब्ध GPIO पिन को आवंटित करने का विकल्प चुन सकता हूं। (यह एक छवि वाले ग्रे हैं)


1
LPC800 भी इसे करने में सक्षम होना चाहिए, क्योंकि कार्यों को पिंस से स्वतंत्र रूप से सौंपा जा सकता है।
Starblue

-1

आप निम्नलिखित की कोशिश कर सकते हैं। अपनी खुद की एक संरचना लिखें, जो 2 बंदरगाहों के संबंधित पिनों (जिनका उपयोग किया जाना है) के लिए मैप करता है। अब इस रजिस्टर में मूल्य को अपडेट करने से उन 2पोर्ट्स के पिन सेट / रीसेट हो जाएंगे। बस कोशिश करो और हमें पता है अगर यह काम किया !!

मुझे विश्वास है कि यह काम करना चाहिए।


2
C में आप किसी मेमोरी लोकेशन में स्ट्रक्चर को मैप कर सकते हैं, और आप अपनी संरचना के बिट्स (बिट फील्ड्स) को बिट ऑफसेट में मैप कर सकते हैं, लेकिन कंपाइलर को 'इनबेटन' बिट्स के साथ गड़बड़ करने से रोकने का कोई तरीका नहीं है, और अब है to समग्र ’संरचना को एक पूर्णांक मान देखने का तरीका। यह काम नहीं करेगा।
राउटर वैन ओइजेन

-1

यदि मैंने प्रश्न को सही ढंग से समझा है, तो यह C में काफी आसान है:

सामान्य प्रकार की घोषणा, किसी भी रजिस्टर के लिए फिर से इस्तेमाल की जा सकती है:

typedef union    // Generic 8-bit register Type
{
  uint8 reg; // Whole register
  struct
  {
    unsigned  bit7     : 1;  // Bit 7 
    unsigned  bit6     : 1;  // Bit 6 
    unsigned  bit5     : 1;  // Bit 5 
    unsigned  bit4     : 1;  // Bit 4 
    unsigned  bit3     : 1;  // Bit 3 
    unsigned  bit2     : 1;  // Bit 2 
    unsigned  bit1     : 1;  // Bit 1 
    unsigned  bit0     : 1;  // Bit 0 
  } bit;
} typ_GENERIC_REG8;

इसलिए, एक बंदरगाह को परिभाषित करने के लिए जिसे हम संबोधित करना चाहते हैं:

#define MCU_GPO_PORTx   (*(volatile typ_GENERIC_REG8 *)(0x12345678)) // Number is address

और उस पोर्ट पर एक पिन को सीधे ट्विस्ट करने के लिए:

#define MCU_PORTx_PINn  (MCU_GPO_PORTx.bit.bit0)

कोड में:

MCU_PORTx_PINn = 1; // Set pin high

संपूर्ण रजिस्टर:

MCU_GPO_PORTx.reg = 0xF; // All pins high

अच्छी तरह से संरचना, यूनियनों, टाइपडिफ्स और एनमों पर पढ़ने के लायक हैं - ये सभी जीवन को एम्बेडेड और सामान्य रूप से बहुत अच्छे बनाते हैं!


ओपी विभिन्न बंदरगाहों से कई बिट्स को 'एक बाइट' में मिलाना चाहता है। मैं नहीं देखता कि यह कैसे होगा? ओलिन लेट्रोप बताते हैं कि यह क्यों संभव नहीं है।

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