SAM3X8E (Arduino ड्यू) पिन IO पंजीकृत करता है


9

Arduino ड्यू के IO रजिस्टर कैसे काम करते हैं? Arduino ऊनो सिर्फ सेट पर DDRxहै, तो PINxपढ़ने के लिए, PORTxलिखने के लिए, मैं एक Arduino कारण के साथ एक ही बात करना चाहते हैं, लेकिन यह इस तरह के रूप में कई और अधिक रजिस्टर, है PIO_OWER, PIO_OSER, PIO_CODR, PIO_SODR, आदि मैं Arduino ऊनो और दोनों के बीच कोई पत्राचार लगता है Arduino ड्यू रजिस्टर।

वहाँ भी कुछ उपयोगी कार्यों जैसे हैं pio_clear, pio_set, pio_get, और दूसरों को, सब यहाँ विस्तार से बताया:

http://asf.atmel.com/docs/3.19.0/sam3x/html/group__sam__drivers__pio__group.html

अब, मुझे लगता है कि मैंने समझा है कि तीन उल्लिखित कार्य क्या करते हैं, लेकिन अन्य नहीं, उदाहरण के लिए:

pio_configure (Pio *p_pio, const pio_type_t ul_type, const uint32_t ul_mask, const uint32_t ul_attribute)

मैं समझ नहीं पा रहा हूं कि क्या ul_attributeऔर क्या ul_typeहैं।


यहां एक GPIO क्लास है जिसे AVR और SAM के लिए लागू किया गया है। रजिस्टर का उपयोग करने का एक संकेत दे सकता है: github.com/mikaelpatel/Arduino-GPIO/blob/master/src/Hardware/…
Mikael Patel

जवाबों:


7

यदि आपके पास यहां से उपलब्ध डेटशीट की धारा 31 का वाचन है , तो चीजें आपके लिए थोड़ी स्पष्ट हो सकती हैं।

यहाँ एक सारांश है जो मुझे पता है:

पीआईओ समानांतर इनपुट / आउटपुट के लिए खड़ा है और एक बार में कई रजिस्टर पोर्ट पढ़ने और लिखने के लिए कार्यक्षमता प्रदान करता है। जहां डेटाशीट में एक रजिस्टर का उल्लेख है, उदाहरण के लिए PIO_OWER, Arduino लाइब्रेरी में उन्हें इस प्रारूप REG_PIO तक पहुंचने के लिए मैक्रोज़ हैं? _OWER कहां? उपलब्ध पोर्ट के लिए या तो ए, बी, सी या डी है।

मैं अभी भी धीमे Arduino pinMode () फ़ंक्शन का उपयोग पिनों पर इनपुट / आउटपुट सेट करने के लिए करता हूं क्योंकि यह कोड को रेजगारी आधारित रजिस्टरों जैसे REG_PIOC_OWER = 0xdeadbeef से अधिक पठनीय बनाता है, लेकिन फिर पिनों को सेट करने के लिए डायरेक्ट रजिस्टरों का उपयोग करें प्रदर्शन / तुल्यकालन। अभी तक, मैंने इनपुट के साथ कुछ भी नहीं किया है, इसलिए मेरे उदाहरण सभी आउटपुट आधारित हैं।

बुनियादी उपयोग के लिए, आप आउटपुट लाइनों को उच्च और REG_PIO? _CODR को कम सेट करने के लिए REG_PIO? _SODR का उपयोग करेंगे। उदाहरण के लिए REG_PIOC_SODR = 0x00000002 PORTC पर बिट 1 (शून्य से क्रमांकित) सेट होगा (यह देय डिजिटल पिन 33 है)। PORTC पर अन्य सभी पिन अपरिवर्तित रहते हैं। REG_POIC_CODR = 0x00000002 PORTC कम पर 1 सेट करेगा। फिर से अन्य सभी पिन अपरिवर्तित होंगे।

जैसा कि यह अभी भी इष्टतम नहीं है, या सिंक्रनाइज़ नहीं है यदि आप समानांतर डेटा के साथ काम कर रहे हैं, तो एक रजिस्टर है जो आपको एक कॉल के साथ पोर्ट के सभी 32 बिट्स लिखने की अनुमति देता है। ये REG_PIO! _ODSR हैं, इसलिए REG_PIOC_ODSR = 0x00000002 अब PORTC उच्च पर 1 बिट सेट करेगा और PORTC पर अन्य सभी बिट्स एक ही CPU निर्देश में कम सेट किए जाएंगे।

क्योंकि यह संभावना नहीं है कि आप कभी ऐसी स्थिति में होंगे जहां आपको एक ही समय में पोर्ट के सभी 32 बिट्स सेट करने की आवश्यकता होती है, आपको पिंस के वर्तमान मूल्य को संग्रहीत करने की आवश्यकता होगी, और उन लोगों को बाहर निकालने के लिए AND ऑपरेशन करें। बदलना चाहते हैं, या जो आप सेट करना चाहते हैं उसे सेट करने के लिए OR ऑपरेशन करें फिर अपना लेखन और फिर से प्रदर्शन करें, और यह इष्टतम नहीं है। इसे दूर करने के लिए, सीपीयू स्वयं आपके लिए मास्किंग करेगा। OWSR (आउटपुट राइट स्टेटस रजिस्टर) नामक एक रजिस्टर होता है, जो ODSR को लिखने वाले किसी भी बिट को OWSR में सेट बिट्स से मेल नहीं खाता है।

इसलिए, अब यदि हम REG_PIOC_OWER = 0x00000002 (यह OWSR का 1 बिट सेट करता है) और REG_PIOC_OWDR = 0xfffffd (OWSR के बिट 1 को छोड़कर सभी बिट्स को साफ करता है) और फिर REG_PIOC_ODSR = 0x00000002 पर कॉल करते हैं। PORTC और अन्य सभी बिट्स अपरिवर्तित रहते हैं। तथ्य यह है कि करने के लिए वेतन ध्यान OWER सक्षम बनाता है किसी भी बिट्स 1 की तैयारी में हैं कि मूल्य आप लिखते हैं और उस OWDR अक्षम कर देता है किसी भी बिट्स 1 की तैयारी में हैं कि मूल्य तुम लिखो में। भले ही मैं इसे पढ़ते समय इसे समझ गया था, फिर भी मैंने अपना पहला टेस्ट कोड यह सोचते हुए कोड गलती करने में कामयाब रहा कि OWDR अक्षम बिट्स जो मेरे लिखे मूल्य में 1 पर सेट नहीं थे

मुझे उम्मीद है कि इसने कम से कम आपको देय CPU के PIO को समझने में थोड़ी शुरुआत दी है। एक पढ़ने और एक नाटक है और यदि आपके कोई और प्रश्न हैं, तो मैं उनका उत्तर देने का प्रयास करूंगा।

संपादित करें: एक और बात ...

आप कैसे जानते हैं कि PORTs के कौन से बिट्स ड्यू की डिजिटल लाइनों के अनुरूप हैं? इसे देखें: ड्यू पिनआउट


3

बुनियादी प्रत्यक्ष पिन पहुंच के लिए काफी सरल तुल्यता है। नीचे कुछ सैंपल कोड दिए गए हैं जिनसे पता चलता है कि कैसे डिजिटल पिन को हाई और फिर लो सेट करना है। पहला एक Arduino ड्यू के लिए है, दूसरा Arduino Uno / Mega / etc के लिए है।

const unsigned int imThePin = 10; //e.g. digital Pin 10

#ifdef _LIB_SAM_

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    Pio* imThePort = g_APinDescription[imThePin].pPort; 
    unsigned int imTheMask = g_APinDescription[imThePin].ulPin; 

    //Lets set the pin high
    imThePort->PIO_SODR = imTheMask;
    //And then low
    imThePort->PIO_CODR = imTheMask;

#else

    //First lets get the pin and bit mask - this can be done once at the start and then used later in the code (as long as the variables are in scope
    volatile unsigned char* imThePort = portOutputRegister(digitalPinToPort(imThePin)); 
    unsigned char imTheMask = digitalPinToBitMask(imThePin);

    //Lets set the pin high
    *imThePort |= imTheMask;
    //Now low
    *imThePort &= ~imTheMask;

#endif

ऐसा करने के लिए जो कुछ भी आवश्यक है, उसे डिफ़ॉल्ट रूप से शामिल किया जाना चाहिए - और यदि नहीं, तो #include <Arduino.h>इसे प्राप्त करने के लिए पर्याप्त होना चाहिए।

वास्तव में ऐसे फ़ंक्शंस उपलब्ध Pioहैं जिन्हें सेटिंग / क्लीयरिंग / पुलअप रेसिस्टर्स / आदि करने के लिए पॉइंटर लगाने के बाद एक बार कॉल किया जा सकता है । थोड़ा क्लीनर का उपयोग कर फ़ंक्शन कॉल करना। एक पूरी सूची में पाया जा सकता है शीर्ष लेख फ़ाइल।


0

यह एक कोड उदाहरण है जो पिन 33 पर एक एलईडी फ्लैश करता है। कोड ऊपर से उधार लिया गया है - बहुत उपयोगी स्पष्टीकरण के लिए बहुत धन्यवाद :) यह एक टीएफटी टचस्क्रीन डिस्प्ले पर 16 बिट रंग पिक्सेल डेटा की डंपिंग के साथ बात करने के लिए एक परियोजना की शुरुआत है जिसकी आवश्यकता है बंदरगाहों तक तेजी से पहुंच। मुझे लगता है कि मेरे पास कोड सही है - विशेष रूप से लाइन जो पिन कम सेट करती है। नेतृत्व खुशी से चमक रहा है।

void setup() 
{
  pinMode(33, OUTPUT); 
  REG_PIOC_OWER = 0x00000002; 
  REG_PIOC_OWDR = 0xfffffffd; 
}

void loop() 
{
  REG_PIOC_ODSR = 0x00000002; 
  delay(1000);             
  REG_PIOC_ODSR = 0x00000000;    
  delay(1000);   
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.