2009-10-24 11 views
5

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

जब मैं माइक्रोकंट्रोलर से डेस्कटॉप पर कुछ भेजता हूं और डेस्कटॉप पर प्रोग्राम भेजता है तो संचार ठीक काम करता है तो फिर माइक्रोकंट्रोलर को कुछ भेजता है।

हालांकि, जब मुझे नियंत्रक से डेस्कटॉप प्रोग्राम तक लगातार जानकारी प्राप्त करने की आवश्यकता होती है जब तक कि डेस्कटॉप प्रोग्राम एक विशेष उत्तर नहीं भेजता है, यह काम नहीं करता है।

यहाँ मैं किस बारे में बात कर रहा हूँ के लिए कोड है:

unsigned char ans = 'N'; 
    unsigned int count = 0; 

    void main(void) 
    { 


     while(1) 
     { 
      if(count == 0) 
      { 
       Configure(); 
       count = 1; 
      } 

        //there is some more code here but is irrelevant to the serial communication 

     } 

    } 


void Configure() 
{ 


    //Repeat this until the user accepts the sent string as correct 
    while(ans == 'N') 
    { 

     BuildString(); 
     Send(); 
     Receive(); 
    } 
} 

void Send() 
{ 
    unsigned int i; 

    TMOD = 0x20; 
    TH1 = 0xFD; 
    SCON = 0x50; 
    TR1 = 1; 

    for(i=0; i<4; i++) 
    { 
     SBUF = toSend[i]; 
     while(TI == 0); 
     TI = 0; 
    } 

} 

void Receive() 
{ 
    unsigned int j; 

    TMOD = 0x20; 
    TH1 = 0xFD; 
    SCON = 0x50; 
    TR1 = 1; 


    for(j=0; j<2; j++) 
    { 
     while(RI == 0); 
     Received[j] = SBUF; 
     RI = 0; 
    } 


    if(count == 0) 
     ans = Received[1]; 

    else 
    { 
     RunType = Received[0]; 
     Move = Received[1]; 
    } 


} 

BuildString() फ़ंक्शन बस कुछ सेंसर आदानों के आधार पर एक स्ट्रिंग निर्माण करती है। प्रेषण और प्राप्त कार्य आमतौर पर ठीक काम करते हैं, लेकिन जब मुझे लगातार भेजने और प्राप्त करने की आवश्यकता होती है, जैसे उपरोक्त कॉन्फ़िगर() फ़ंक्शन में, यह काम नहीं करता है।

कोई सुझाव? मैं वास्तव में उनकी सराहना करता हूं।

+0

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

उत्तर

4

समस्या यह है कि दोनों अपने भेजने और प्राप्त कार्यों सर्वेक्षण में शामिल और अवरुद्ध कर रहे हैं। जब आप प्राप्त फ़ंक्शन को कॉल करते हैं, तो यह केवल एक पूर्ण संदेश प्राप्त होने के बाद ही वापस आ जाएगा। प्रेषण समारोह के लिए डिटो, लेकिन अवधि भेजने के मामले में काफी छोटा है (आपका प्रोग्राम केवल संदेश भेजने के लिए कॉल करने पर ही कॉल करेगा, जबकि संदेश प्राप्त होने से कुछ दिन पहले इंतजार कर सकता है।

यदि आप एसिंक्रोनस कम्यूनिकेशन की आवश्यकता है, सबसे अच्छा इंटरप्ट आधारित संचार का उपयोग करना है; कम से कम प्राप्त करने और प्राप्त करने के लिए प्राप्त करने और आदर्श दोनों के लिए।

प्रदूषित संचारों का उपयोग करके इसे लागू करना भी संभव है, लेकिन फिर आपको एक फ़ंक्शन लिखना होगा चेक करता है कि कोई चरित्र प्राप्त करने के लिए (या यदि टीएक्स-रिक्त) प्राप्त होता है, तो अगले वर्ण को/से बफर से पढ़ने/लिखने के लिए।

बाधा के फायदे ased संचार कर रहे हैं:

  • फुल डुप्लेक्स
  • कम CPU समय प्रयोग किया जाता है (कोई प्रतीक्षा लूप आवश्यक)
  • कम बिजली (यह बाधा पर वेकअप के साथ, एक कम बिजली/स्टैंडबाई मोड में जाने के लिए अनुमति देता है cpu ; मतदान के लिए हमेशा पूर्ण शक्ति की आवश्यकता होती है)

पहले चरण के रूप में मैं आपको एक इंटरप्ट आधारित प्राप्त करने (या प्राप्त) करने के लिए सलाह देता हूं; यहां तक ​​कि जब ट्रांसमिट फ़ंक्शन अभी भी अवरुद्ध है, तो यह न्यूनतम प्रयास के साथ पूर्ण डुप्लेक्स ऑपरेशन की अनुमति देगा। यदि आपके पास ओएस (आरटीओएस/शेड्यूलर) नहीं है तो आपको सिंक्रनाइज़ेशन तंत्र के बारे में सोचना होगा। यदि कोई उपलब्ध है तो संदेश प्राप्त करने के लिए सबसे सरल रूप है, और यदि कोई (पूर्ण) संदेश नहीं है तो तुरंत लौटने के लिए।

शुभकामनाएं।

टिप्पणी संदेश-दर-संदेश आधार पर के बाद संपादित करें, बातें करता है, तो डेस्कटॉप नियंत्रक द्वारा भेजे गए संदेश पर प्रतिक्रिया कर रहा है काम करने के लिए लग सकता है। यदि आपके नियंत्रक के पास प्राप्त होने पर एक बड़ा फीफो बफर (यानी 64 बाइट्स) है, तो यह काम कर सकता है। मुझे पता है कि अधिकांश नियंत्रकों को यह नहीं मिला है। कई में केवल एक ही वर्ण बफर होता है। आप रजिस्टरों में ओवरव्लो बिट का उपयोग करके इसका पता लगा सकते हैं; यदि यह सेट है, तो प्राप्त होने पर अक्षर खो गए थे।

कुछ usecases: * यदि आप एक ही बार में 2 संदेश भेजना चाहते (जैसे: + init do_something)। पीसी पहले संदेश का जवाब देता है, लेकिन नियंत्रक अभी भी अधिकांश डेटा भेज रहा है और छोड़ देता है। * नियंत्रक प्राप्तकर्ता() फ़ंक्शन निष्पादित करने से पहले पीसी भेजना शुरू कर देता है। पैकेट की शुरुआत में डेटा खो सकता है * संचार में किसी भी बूंद से डेडलॉक हो सकता है (यानी नियंत्रक और डेस्कटॉप दोनों दूसरे भेजने के लिए इंतजार कर रहे हैं।

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

ए rs232 मॉनीटर आपकी मदद कर सकता है (इसके लिए आपको कुछ अतिरिक्त बंदरगाहों की आवश्यकता होगी। कई (फ्रीवेयर सहित) अनुप्रयोग हैं जो एकाधिक rs232 बंदरगाहों की निगरानी कर सकते हैं और टाइमस्टैम्प प्रदान कर सकते हैं। इसलिए आप संचार के आदेश का निरीक्षण कर सकते हैं। Google ने मुझे पाया: link; I कई simil इस्तेमाल किया है पिछले वर्षों में आर यूटिलिटीज।

+0

आपके सुझाव Adriaan के लिए बहुत बहुत धन्यवाद। लेकिन मैं उलझन में हूं। मुझे लगता है कि यह अवरोधक पहलू के कारण काम नहीं कर रहा है, लेकिन मुझे लगा कि जिस तरह से मैंने अपने कार्यक्रम लिखे थे, वे इसके आसपास मिल गए होंगे। देखें कि मैं नियंत्रक एक संदेश भेजता हूं, जबकि डेस्कटॉप प्रोग्राम इसे प्राप्त करने के साथ प्रतीक्षा कर रहा है() फिर डेस्कटॉप प्रोग्राम संदेश को जांचता है कि यह स्वीकार्य है (यह सब जबकि नियंत्रक प्रोग्राम प्राप्त करने का इंतजार कर रहा है) और फिर भेजता है एक संदेश सिग्नलिंग स्वीकृति या संदेश की अस्वीकृति। अवरुद्ध करने वाले नियंत्रक में प्राप्त() अब अनब्लॉक किया गया है ना? – CodeConfused

+0

तो क्या यह सिर्फ शेष कोड के साथ आगे बढ़ना नहीं चाहिए? यह जांच है कि प्राप्त संदेश स्वीकृति या अस्वीकृति के लिए है (इस समय के दौरान डेस्कटॉप कंप्यूटर अवरुद्ध प्राप्त करने के साथ प्रतीक्षा कर रहा है) और फिर संदेश फिर से भेजें? मुझे यकीन है कि एसिंक्रोनस संचार इस प्रोबेलम को हल करेगा जैसा आपने कहा था, लेकिन मैं इस परियोजना के साथ एक समय सीमा पर हूं और मैंने कभी भी एसिंक्रोनस कॉम की कोशिश नहीं की है। इससे पहले कि अगर आप सिंक्रोनस के साथ इसे हल करने में मदद कर सकते हैं तो मैं वास्तव में वास्तव में सराहना करता हूं! – CodeConfused

+0

उत्तर में संपादित देखें। – Adriaan

1

आपके प्रोग्राम को लिखे गए अनुसार 4 बाइट भेजना चाहिए और फिर 2 बाइट्स पढ़ना चाहिए। (मान लें कि आपके पास रजिस्ट्रार सही हैं, लेकिन यदि आपको यह काम करने के लिए मिल गया तो वे शायद सही हैं) फिर 4 बाइट दोबारा भेजें ... यह शायद भेजने के हिस्से पर लटका नहीं है लेकिन प्राप्त करने वाला पक्ष है क्योंकि यह हमेशा दो बाइट पढ़ने का इंतजार कर रहा है, और अगर किसी कारण से दो बाइट इनपुट रजिस्टर पर नहीं पहुंचते हैं तो आप हमेशा के लिए इंतजार करना जारी रखेंगे।

यह हो सकता है कि जब आप सिस्टम पर दबाव डालते हैं (बाइट बहुत तेज़ी से भेजते हैं) तो आप इनपुट बफर को बहते हैं और बाइट खो देते हैं? इस प्रकार दो बाइट कभी नहीं मिल रहा है। और फंस जाएगा।

  1. क्या आप डीबग कर सकते हैं जहां आप फंस रहे हैं? वास्तव में यह प्राप्त पाश में है?
  2. क्या आप पीसी से माइक्रो तक ट्रांसमिशन को थ्रॉटल कर सकते हैं ताकि आप एक समय में मैन्युअल रूप से एक बाइट भेज सकें?
  3. माइक्रो और एक्सबी इंटरफ़ेस के बीच कोई हैंडशेकिंग है? क्या माइक्रो द्वारा थ्रॉटल किया जा सकता है?
+0

हाँ साइमन आप सही हैं, इसे 4 बाइट भेजना चाहिए, फिर एक निश्चित उत्तर प्राप्त होने तक 2 प्राप्त करें। मुझे यकीन है कि समस्या प्राप्त भाग में झूठ बोलता है, बस क्योंकि एक्सबीज भेजते या प्राप्त करते समय प्रकाश डालते हैं। इसलिए मैं देख सकता हूं कि डेस्कटॉप प्रोग्राम से 2 बाइट डेस्कटॉप छोड़ चुके हैं और उन्हें माइक्रोक्रोनरोलर पर पहुंचने के लिए 'देख' भी सकते हैं। नियंत्रक कोड उसके बाद इसे संभाल नहीं करता है। मैंने आपके द्वारा एक बार में बाइट्स मैन्युअल रूप से भेजकर डीबग करने का प्रयास किया था। लेकिन यह अभी भी काम नहीं कर रहा है। – CodeConfused

+0

मुझे माइक्रो के बीच हैंडशेकिंग के बारे में निश्चित नहीं है और Xbee। लेकिन मुझे यकीन है कि वहाँ नहीं है। – CodeConfused

+0

@CudeConfused, क्या आप यह निर्धारित कर सकते हैं कि आरआई बिट कितनी बार बदला जा रहा है? कुछ कैसे कुछ बार एक बाइट समाप्त करना आरआई बिट सेट नहीं किया जा रहा है। क्या इससे पहले कि आप इसे साफ़ करने से पहले आरआई को ट्रिगर कर रहे हों और इस प्रकार दूसरी बाइट याद आती है? – simon

संबंधित मुद्दे