كيف يمكنني إرسال سلسلة بشكل تسلسلي من 8051 مرة واحدة فقط؟

StackOverflow https://stackoverflow.com/questions/1216376

سؤال

أقوم بإنشاء وحدة تحكم دقيقة 8051 تتواصل لاسلكيًا مع جهاز الكمبيوتر.سوف يرسل المتحكم الدقيق سلسلة إلى المنفذ التسلسلي الخاص به (DB9) وسيستقبل الكمبيوتر هذه السلسلة ويتعامل معها.

مشكلتي هي أنني لا أعرف كيفية جعل 8051 ينقل السلسلة مرة واحدة فقط.نظرًا لأنني بحاجة إلى التعامل مع السلسلة الموجودة في نهاية جهاز الكمبيوتر، فيجب استلامها مرة واحدة فقط.حاليًا، على الرغم من أنني أرسل السلسلة مرة واحدة في كود C، إلا أنني أتلقى نفس السلسلة بشكل مستمر على جهاز الكمبيوتر الخاص بي.أفترض أن السبب في ذلك هو أن كل ما هو موجود في SBUF يتم إرساله بشكل مستمر.هل هناك أي طريقة يمكنني من خلالها إرسال سلسلتي مرة واحدة فقط؟هل هناك طريقة لتفريغ SBUF؟

حاولت استخدام دبوس RTS (طلب الإرسال) (الدبوس السابع) على DB9 لأنني قرأت في مكان ما أنه إذا قمت بإلغاء الجهد الكهربي على هذا الدبوس فإنه سيوقف تدفق البيانات إلى المنفذ التسلسلي.إذن ما فعلته هو برمجة وحدة التحكم الدقيقة الخاصة بي لإرسال السلسلة ثم إرسال المستوى المنطقي 0 إلى طرف الإخراج الذي كان متصلاً بدبوس DB9 RTS الخاص بي.ومع ذلك، فإن ذلك لم ينجح.

هل يوجد لدى احد أي اقتراحات؟سأقدرهم حقًا.

يحرر

البرنامج الذي أستخدمه على جهاز الكمبيوتر هو X-CTU لوحدات Xbee.هذا هو الكود الموجود على وحدة التحكم الدقيقة الخاصة بي:

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  

هل يمكن لشخص ما التحقق من أنه في الواقع يرسل السلسلة مرة واحدة فقط؟

يحرر

يبدو أن ستيف وبروكسموز ونيل قد أصابوا رأسهم عندما قالوا إن ما كان يحدث بعد وظيفتي الرئيسية هو الذي تسبب في المشكلة.لقد جربت للتو الكود المقترح الذي طرحه ستيف (وبشكل أكثر تحديدًا for(;;);وتحديد serTX خارج النطاق الرئيسي) وعمل بشكل مثالي.من المحتمل أن يتم إعادة تشغيل وحدة التحكم ومن ثم يستمر نفس الكود في تكرار نفسه.

شكرا جزيلا علي المساعدة!:)

هل كانت مفيدة؟

المحلول

هل يمكنك التأكد من أن جهاز 8051 يرسل البيانات مرة واحدة فقط؟تتمثل إحدى طرق التحقق في استخدام نطاق لمعرفة ما يحدث على دبوس TX الخاص بـ UART.

ما هي البرامج التي تستخدمها على جهاز الكمبيوتر؟أقترح استخدام برامج اتصالات بسيطة مثل HyperTerminal أو المعجون.إذا كانوا يظهرون أن السلسلة يتم إرسالها إلى جهاز الكمبيوتر عدة مرات، فمن المحتمل أن يكون الخطأ في البرنامج الذي يعمل على 8051.

يحرر: لكي نكون صادقين، يبدو هذا وكأنه نوع من تصحيح الأخطاء الذي يتعين على المهندسين مواجهته بشكل منتظم، وبالتالي فهي فرصة جيدة لك لممارسة حل المشكلات بطريقة منهجية قديمة الطراز.

إذا كنت صريحًا جدًا، أقترح عليك القيام بما يلي:

  1. تصحيح.جرب الأشياء، ولكن لا تخمن.تجربة.قم بإجراء تغييرات صغيرة في التعليمات البرمجية الخاصة بك وشاهد ما سيحدث.جرب كل ما يمكنك التفكير فيه.ابحث في الويب لمزيد من المعلومات.
  2. إذا لم يؤدي ذلك إلى حل، فارجع هنا وزودنا بجميع المعلومات التي نحتاجها.يتضمن ذلك الأجزاء ذات الصلة من التعليمات البرمجية، والتفاصيل الكاملة للأجهزة التي تستخدمها، ومعلومات حول ما جربته في الخطوة 1.

يحرر: ليس لدي مندوب لتعديل السؤال، لذا إليك الكود الذي نشرته OP في التعليق على سؤالها:

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    void SerTx(unsigned char x)
        { SBUF = x; while(TI==0); TI = 0; } 
}

كما ذكر نيل وبروكسموسز في إجاباتهما، في النظام المضمن، لا يُسمح أبدًا بإنهاء الوظيفة الرئيسية.لذا، يتعين عليك إما وضع التعليمات البرمجية الخاصة بك في حلقة لا نهائية (وهو ما قد يحدث عن غير قصد)، أو إضافة حلقة لا نهائية في النهاية، بحيث يتوقف البرنامج بشكل فعال.

أيضًا، يجب تعريف الدالة SerTx خارج main.قد يكون هذا صحيحًا من الناحية النحوية، لكنه يبقي الأمور بسيطة ولا يعلن عن وظائف ضمن وظائف أخرى.

لذا جرب هذا (لقد أضفت أيضًا بعض التعليقات في محاولة لتسهيل فهم الكود):

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    /* Initialise (need to add more explanation as to what
        each line means, perhaps by replacing these "magic
        numbers" with some #defines) */
    TMOD = 0x20;
    TH1  = 0xFD;
    SCON = 0x50;
    TR1  = 1;

    /* Transmit data */
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    /* Stay here forever */
    for(;;) {}

}

void SerTx(unsigned char x)
{
    /* Transmit byte */
    SBUF = x;

    /* Wait for byte to be transmitted */
    while(TI==0) {}

    /* Clear transmit interrupt flag */
    TI = 0;
} 

نصائح أخرى

لا تحتوي التعليمات البرمجية التي نشرتها على حلقة في main()، لذا تحتاج إلى تحديد ما يفعله وقت تشغيل المترجم الخاص بك عندما يعود main() بعد إرسال "Y".نظرًا لمشكلتك، أتخيل أن المترجم يقوم بإنشاء بعض التعليمات البرمجية لإجراء بعض عمليات التنظيف ثم إعادة تشغيل الجزء الصغير (ربما إعادة تعيين الأجهزة، وربما يتم إعادة تشغيل وقت تشغيل C فقط).يبدو أن برنامجك يعمل تمامًا كما كتبته، ولكنك تجاهلت ما يحدث قبل وبعد استدعاء main().

إذا كنت تريد إرسال السلسلة الخاصة بك مرة واحدة فقط، على الإطلاق، فأنت بحاجة إلى شيء من هذا القبيل while(1) {} تتم إضافتها بعد إرسال الحرف الأخير.لكن برنامجك لا يفعل شيئًا، بل سينفذ حلقة فارغة إلى الأبد.يلزم إعادة التعيين (مثل تدوير الطاقة) للبدء من جديد وإرسال السلسلة.

لاحظ أنه إذا كان جهاز Micro الخاص بك مزودًا بمؤقت مراقبة، فقد يتدخل ويفرض إعادة تعيين غير متوقعة.إذا حدث هذا، فسيتم إرسال السلسلة الخاصة بك مرة واحدة لكل عملية إعادة تعيين للمراقبة (والتي يمكن أن تكون مرة واحدة كل ثانية، ويعتمد المعدل على أجهزتك).

وأيضًا، ربما لا يكون تعريف serTx() متداخلًا داخل main() هو ما تريده.

وانه من الصعب ان نقول ما هي المشكلة دون رؤية أي من التعليمات البرمجية 8051. على سبيل المثال، يمكن لخطأ منطقي على هذا الجانب يؤدي إلى البيانات التي يتم إرسالها عدة مرات، أو برنامج 8051 قد تنتظر لACK التي يتم تلقيها أبدا، وما إلى ذلك.

عادة على رمز 8051 ولإرسال صراحة كل حرف، ولكن أفترض تؤخذ هذه الرعاية لك من قبل C وقت التشغيل.

واستعمال RTS / CTS (طلب إرسال / مسح للإرسال) هو للسيطرة على تدفق (أي لمنع التجاوزات العازلة - مخازن وعادة ما تكون صغيرة جدا على هذه ميكروكنترولر). وليس لوقف انتقال تماما

ومرددا الجواب نيل (في الرد، لأنني لم يكن لديك مندوب التعليق): في الوضع متحكم نموذجي دون OS، انها لم يتضح على الفور ما وظيفة الخروج () أن يحصل على استدعاء ضمنيا في نهاية من main () يجب القيام به - أو بشكل أدق، فإنه لا يمكن القيام به من المعتاد "إنهاء البرنامج والعودة إلى نظام التشغيل"، لأنه ليس هناك OS العودة إلى

وعلاوة على ذلك، في تطبيق حقيقي، وتريد أبدا تقريبا برنامج لوقف فقط، إلا إذا قمت بإيقاف تشغيل النظام. ذلك شيء واحد أن تنفيذ خروج () يجب بالتأكيد لن تفعل غير يستغرق الكثير من المساحة التعليمات البرمجية.

في بعض الأنظمة عملت على، لم يتم تنفيذ الخروج () الواقع على الإطلاق - إذا كنت لا تنوي استخدام ذلك، حتى لا تضيع بايت على ذلك! والنتيجة هي أنه عندما يحصل على مسار تنفيذ إلى نهاية الرئيسية ()، ورقاقة يتجول قبالة إلى أرض لالا لتنفيذ كل ما يحدث أن تكون في بت المقبل من الذاكرة، وعادة بسرعة ينتهي إما عالقة في حلقة أو يخطأ مع شفرة تشغيل غير قانوني. والنتيجة المعتادة لخطأ مع شفرة التشغيل غير القانوني ... إعادة التشغيل الرقاقة.

وهذا يبدو وكأنه نظرية plausable عن ما يحدث هنا.

وهذه مادة معينة هي لتجميع، وليس C، ولكن قد تكون مفيدة: http://www.8052.com/tutser.phtml

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top