اطلاعیه

Collapse
No announcement yet.

|؟| چرا باید از وقفه سریال استفاده کنم؟

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    |؟| چرا باید از وقفه سریال استفاده کنم؟

    سلام خدمت همراهان همیشگی ECA!
    اساسا خیلی دلم میخواد کاری که انجام میشه اصولی و حتی الامکان عاری از مشکل و باگ باشه(گرچه این وضعیتیست ایده آل!)

    خب بریم سر اصل مطلب!:
    فرض کنید ما یه ارتباط سریال(UART) داریم که در اون میکرو هر یه ثانیه اطلاعات رو دریافت میکنه(مثلا از ماجول GPS) که شروع ارتباط رو می دونیم که حتما با کاراکتر '$' هستش
    حال سوال اینه که: آیا در این مورد استفاده از وقفه سریال الزامیست؟ چه الزامی دارد؟ اگر الزامی نیست، فایده و مزیت آن چگونه است؟(تا حالا که بدون استفاده از وقفه سریال برنامه به خوبی جواب داده،اما کمی وسواس دارم!)
    با تشکرقبلی از تمامی دوستان...
    اونچيزي که در دانشگاه ياد ميگيريد، "الفبايي" هست براي نوشتن يک "رمان" !!

    #2
    پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

    موضوع سر اینه
    Data lost
    سخت افزار AVR طوریه که اگه یه بایتی به پورت سریال برسه و اونو نخونی و بایت بعدی برسه بایت قبلی از بین میره و پر.
    حالا اگه فکر میکنی این اتفاق تو برنامه شما (کاملا به ساختار برنامه بستگی داره) نمیافته که هیچی.
    اما اگه از delay های طولانی استفاده می کنی و به هر دلیل دیگه امکانش هست باید داده ها رو به محض رسیدن پردازش کنی تا Data Lost اتفاق نیافته.
    بت در بغل و به سجده پیشانی ما کافر زده خنده بر مسلمانی ما
    اسلام به ذات خود ندارد عیبی هر عیب که هست در این مسلمانی ماست

    دیدگاه


      #3
      پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

      نوشته اصلی توسط mostafahk
      موضوع سر اینه
      Data lost
      سخت افزار AVR طوریه که اگه یه بایتی به پورت سریال برسه و اونو نخونی و بایت بعدی برسه بایت قبلی از بین میره و پر...
      ممنون
      اما برنامه من طوریه که به محض دریافت کاراکتر '$'، الباقی کاراکترها رو نیز بدون تاخیر دریافت میکنه
      بنابراین استفاده از وقفه سریال، یک عمل استاندارد و روتین در کار با UART محسوب نمیشه،درسته؟
      اونچيزي که در دانشگاه ياد ميگيريد، "الفبايي" هست براي نوشتن يک "رمان" !!

      دیدگاه


        #4
        پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

        شما که نمیدونی کاراکتر $ کی قراره بیاد. اگه موقعی که برنامه داره رو LCD چیزی مینویسه یا کیپد رو میخونه بیاد چی؟ به اینها فکر کردید؟ اگه این مشکلات
        پیش نمیاد که مسئله ای نیست ولی کلا برای یه کار حرفه ای و مطمئن باید جانب احتیاط رو رعایت کرد و تو وقفه اطلاعات رو تو به بافر مثلا 16 بایتی ریختد و تو برنامه اصلی از بافر اطلاعات رو خوند. اینطوری اگه به اندازه 16 بایت برنامه جای دیگه (مثلا تو اسکن کیپد) معطل باشه اطلاعاتی از دست نمیره.

        این کار یه استاندارده ولی برای برنامه های خیلی ساده بیخودی نباید کار رو پیچیده کرد.
        بت در بغل و به سجده پیشانی ما کافر زده خنده بر مسلمانی ما
        اسلام به ذات خود ندارد عیبی هر عیب که هست در این مسلمانی ماست

        دیدگاه


          #5
          پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

          نوشته اصلی توسط ☺بابابرقی☺
          ممنون
          اما برنامه من طوریه که به محض دریافت کاراکتر '$'، الباقی کاراکترها رو نیز بدون تاخیر دریافت میکنه
          بنابراین استفاده از وقفه سریال، یک عمل استاندارد و روتین در کار با UART محسوب نمیشه،درسته؟
          سلام. همونطور که دوستمون آقای مصطفی گفتند این به نوع برنامه نویسی شما بستگی داره.چنانچه زمان اجرای برنامه داخل لوپ اصلی از زمان دریافت سریال 8 بیت بیشتر باشه ناگزیر هستید که از وقفه استفاده کنید. البته برای حل نسبی این مشکل میتونید چند کار انجام بدید یکی اینکه فرکانس میکرو رو بالاتر ببرید(البته اگر از توابع delay استفاده نمیکنید، وگرنه بی فایده است). یا اینکه روتین دریافت رو در یک لوپ پیگیری کنید و زمانی که یک یا چند بایت کامل دریافت شد از حلقه خارج بشید یعنی همون کاری که توابعی مانند scanf در کامپایلرهای C انجام میدهند. ولی در ارتباط نا همزمان (UART )حتی با این روش هم اگر برنامه اصلی طولانی باشه احتمال از دست دادن دیتا وجود داره. دلیلش هم همون ناهمزمان بودنشه. یعنی اینکه شما از زمان ارسال دیتا توسط فرستنده گاهی ندارید. ممکنه زمانی که فرستنده یک پروسه ارسال رو شروع میکنه گیرنده در وسط اجرای یک برنامه دیگه باشه.
          توجه داشته باشید که سیگنال وقفه دریافت در میکروکنترلر حکم سیگنال زنگ در تلفن رو داره.
          پس میکرو بدون استفاده از وقفه زمانی میتونه دریافت رو صحیح انجام بده که تقریباً بیکار باشه و یا اینکه قبلاً با یک سری پروتکل با فرستنده بر سر زمان ارسال توافق کرده باشه.

          دیدگاه


            #6
            پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

            یک مثل معروف در فرهنگ آمریکایی هست که میگه "وقت طلاست" البته بگذریم که اینجا از خیلی چیزای بی ارزش هم (که فکر نمیکنم دیگه چیزی مونده باشه!! :mrgreen بی ارزشتره.
            ولی به هر حال میکرو بایستی در طی یک زمان کار حداکثری رو انجام بده. و اگر کاری برای انجام دادن نداشت هزینه های جنبی اش رو کاهش بده. مثلا از power saving استفاده کنه. تا انرژی کمتری مصرف کنه. یکی از مواردی که روی این دو فاکتور اساسی خیلی تاثیر داره مورد تاخیرات یا delay در برنامه هست. اگر اونطوری که مرسومه از طریق اجرای کد این مورد "تاخیر" صورت بگیره در اصل داریم هم توان تلفاتی میکرو رو بالا میبریم و هم از زمان استفاده درستی نمیکنیم. اینجور مواقع می آییم و از منطق "بروز رویداد" که یکی از مصداق هاش "وقفه" هست استفاده میکنیم. با استفاده از این منطق دو سه تا مکانیسم رو پیاده میکنیم.
            1- مکانیسمی برای شناسایی رویداد که اینجا میشه همون بروز وقفه.
            2- مکانیسمی برای اطلاع این "رویداد" به منطق اجرایی برنامه (مثلا با استفاده از بافر. یا سمافور یا صف پیغام و غیره)
            3- مکانیسمی برای ایجاد تاخیر مبتنی بر power saving. که البته برای این یکی میشه از "وقفه" نهایت استفاده رو کرد.

            غیر از این موارد همون جوری که دوستمون فرمودن مشکل خیلی از وقتها اینه که ما کد اصلی مون بطور همزمان اجرا میشه (سنکرون) ولی ایجاد رویدادها بطور غیر همزمان (آسنکرون) انجام میشه. از طرفی خیلی وقتها به علت محدودیت های سخت افزار بهتره که یک سری عملیات اصلی برنامه در زمینه اجرای کد اصلی انجام بشه. که باز هم میشه از وقفه ها استفاده شایانی کرد. مثلا AVR فقط برای یک بایت بافر سریال داره. یعنی اگر در فاصله دریافت یک بایت داده (که البته برای سریال حداقل 11 بیت هست و نه 8 بیت) نتونیم به پورت سریال سر بزنیم؛ این داده از بین میره. تازه جدای از این مورد در هر جایی از برنامه شما مجبوری به سریال هم سر بزنی. و این یعنی تولید کد اضافه و گیج کردن منطق.

            به عنوان مثال من همیشه از یک منطق این تیپی پیروی میکنم:
            1- در وقفه سریال با استفاده از یک ماشین وضعیت؛ پروتکل پایه ارتباطی رو پیاده سازی میکنم. این پیاده سازی میتونه در حالت کلی فقط بافر کردن بایتهای دریافتی باشه. ولی من یک لایه بالاتر یعنی بحث عیب یابی در تبادل اطلاعات و جدا سازی داده های خام رو هم انجام میدم. اگر در طی دریافت اطلاعات در پورت سریال خطایی رخ بده؛ در صورت امکان در همین لایه (بدون اطلاع برنامه اصلی) پیغام خطا رو برای طرف ارسال کننده اطلاعات؛ ارسال میکنم. و در صورتی که داده ای برای پردازش آماده باشه از طریق یک مکانیسم؛ مثلا استفاده از یک متغیر منطقی آماده بودن درخواستی رو برای پردازش به منطق اصلی اطلاع میدم.

            2- در برنامه اصلی این متغیر رو چک میکنم. (فقط 4 سیکل ساعت احتیاج هست) تا بتونم جواب مورد نیاز رو برای ارسال کننده درخواست ایجاد کنم. و ارسال رو هم به عهده روال وقفه میذارم.

            3- برای delay دادن؛ از یک متغیر عمومی استفاده میکنم تا در زمانی که delay در جریان هست و من مجبورم صبر کنم خودم رو تا وقفه بعدی (که میتونه یک وقفه تایمر یا سریال باشه) در حالت sleep قرار بدم.

            .....

            دیدگاه


              #7
              پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

              ....
              ضمنا یک مورد اساسی که شما در نظر نمیگیری بحث احتمال وقوع خطا هست. یکی از بدترین کارهایی که شما میتونی در برنامه نویسی انجام بدی اینه که فرض کنی همیشه همه چیز اونطور که شما میخوایی پیش میره. اطلاعات بطور درستی منتقل میشن. اطلاعات بدون هیچ تاخیر زمانی از طرف مقابل ارسال میشن و غیره. ملاحظه نکردن این موارد باعث میشه در بعضی اوقات برنامه شما همیشه اونطوری که در نظر داری کار نکنه.
              مثلا این رو فراموش میکنی که GPS (در اینجا البته) یک وسیله ای هست که کار های خودش رو انجام میده. و معلوم نیست همون طوری که شما انتظار داری اطلاعات رو بفرسته. تازه بحث نویز و تاثیر گذاشتن روی اطلاعات دریافتی هم وسطه. تمام اینها به این مرحله میرسه که برنامه شما همیشه 100 درصد قابل اطمینان نیست. جدای از مسئله بروز خطا بحث عدم قطعیت زمانی هم پیش میاد. یعنی در حالت کلی شما نمیتونی گارانتی کنی که انجام یک "کار" در طی چه حداکثر زمانی انجام میشه و قطعیت در این مورد همون چیزی هست که ما بهش میگیم real time.

              البته تمامی این موارد و استفاده از اونها بیشتر سلیقه ای هست. و به دیدگاه برنامه نویس و نیاز ها و مشخصات برنامه بر میگرده.

              دیدگاه


                #8
                پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

                بسیار ممنون دوستان،اطلاعات جالبی کسب کردم
                اما طی تجربه 5ماهه کار با ماجول GPS (که صد البته میدونم کافی نیست) اینطور برداشت کردم:
                (با فرض باودریت9600 و 1هرتز-نرخ ارسال اطلاعات توسط ماجول): در هر سیکل یک ثانیه ای حداکثر 50% سیکل صرف دریافت کامل اطلاعات ماجول میشود(شامل تمام پارمترهایی که ماجول میتواند ارسال کند)، بنابراین حدود 500ms زمان میگذرد، من با این فرض نیازی به وقفه سریال نخواهم داشت(چون 500ms دیگه زمان دارم برای پردازش و نمایش اطلاعات و...)، اما بنا به فرمایش دوستان و عدم قطعیت و احتمال به وجود آمدن تاخیر در ماجول و الباقی موارد احتمالی،ظواهر امر اینگونه پیداست که استفاده از امکان وقفه سریال بر بهینه بودن طرح خواهد افزود.

                آقا رضا در مورد این جملتون:
                برای delay دادن؛ از یک متغیر عمومی استفاده میکنم تا در زمانی که delay در جریان هست و من مجبورم صبر کنم خودم رو تا وقفه بعدی (که میتونه یک وقفه تایمر یا سریال باشه) در حالت sleep قرار بدم
                ایده جالبی هستش! من با مد sleep آشنایی چندانی ندارم(فقط در این حد که یه سری رجیستر رو باید مقدار دهی کنیم!)، اگه امکانش هست کمی بیشتر در این مورد توضیح بدید.
                ممنون...
                اونچيزي که در دانشگاه ياد ميگيريد، "الفبايي" هست براي نوشتن يک "رمان" !!

                دیدگاه


                  #9
                  پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

                  این یک نمونه کد. تحلیلش با خودتون.

                  volatile unsigned int dly_tmo;

                  SIGNAL(SIG_OVERFLOW0)
                  {
                  TCNT0 = ....;

                  if(dly_tmo != 0)
                  dly_tmo--;
                  }


                  void delay(unsigned int timeout)
                  {
                  MCUCR |= 1 << SE;
                  dly_tmo = timeout;
                  while(dly_tmo)
                  asm("sleep"
                  MCUCR &=~(1 << SE);
                  }


                  با فرض اینکه تایمر صفر جوری ست شده که هر 1 میلی ثانیه یک وقفه بده.

                  دیدگاه


                    #10
                    پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

                    نوشته اصلی توسط رضا آقازاده
                    مثلا AVR فقط برای یک بایت بافر سریال داره. یعنی اگر در فاصله دریافت یک بایت داده (که البته برای سریال حداقل 11 بیت هست و نه 8 بیت) نتونیم به پورت سریال سر بزنیم؛ این داده از بین میره.
                    با سلام و تشکر از توضیحات کاملتون. جسارتاً باید عرض کنم حداقل تعداد بیت در سیستم های مختلف متفاوته. در ماشینی مثل AVR این حداقل میتونه 7 بیت هم باشه (5 بیت دیتاو 1 بیت شروع و 1 پایان). ضمناً در قالب استاندارد NRZ هم حداقل 10 بیت است نه 11 بیت.

                    دیدگاه


                      #11
                      پاسخ : |؟| چرا باید از وقفه سریال استفاده کنم؟

                      آره دقیقا! ولی مرسومه که یا 7 و یا 8 بیتی کار میکنن و اغلب به فرم 8N1. وگرنه هر کسی هم میتونه سوپ رو هرتی سر بکشه ولی اولین چیزی که موقع خوردن سوپ در ذهن همه تداعی میکنه وسیله ای بنام قاشق هست. ضمنا فقط در AVR نیست. روی PC هم میشه بایت 5 بیتی داشت. بخاطر همینه که خیلی جاها از واژه octet بجای بایت استفاده میکنن. اگر بخواییم تا این حد ریز بشیم شما به مشکل بر میخوری. من استاد چانه لقی و لفاظی ام. :mrgreen:

                      از طرفی با شبهه 8 بیتی بودن یک بایت وقتی میگین "8 بیت" این رو توی ذهن تداعی میکنه که فریم سریال رو در نظر نگرفتین. مگر اینکه خلافش ثابت بشه.

                      دیدگاه

                      لطفا صبر کنید...
                      X