اطلاعیه

Collapse
No announcement yet.

تداخل وقفه سریال با وقفه تایمر در بیسکام

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

    تداخل وقفه سریال با وقفه تایمر در بیسکام

    سلام من به طور هم زمان مجبورم 5 تا سرو متور و راه بندازم در حالی که باید از ورودی سریال هم دیتا بگیرم ولی مشکل اینجاست که نمیتونم همزمان وقفه هارو فهال کنم وقتی وقفه تایمر 2 فعال هست نمیشه به زیر برنامه وقفه سریال رفت یعنی از سریال هیچ چی دریافت نمی کنه ولی به محض اینکه این خط رو از برنامه پاک میکنیم
    On Timer2 Tim
    که سر برگ وقفه تایمر رو معرفی میکنه برنامه به خوبی کار میکنه
    [move][img width=133 height=100]http://bargiri.persiangig.com/aks/0.306310001356499787_taknaz_ir.gif[/img][/move]

    #2
    پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

    نوشته اصلی توسط حامد رحیمی
    سلام من به طور هم زمان مجبورم 5 تا سرو متور و راه بندازم در حالی که باید از ورودی سریال هم دیتا بگیرم ولی مشکل اینجاست که نمیتونم همزمان وقفه هارو فهال کنم وقتی وقفه تایمر 2 فعال هست نمیشه به زیر برنامه وقفه سریال رفت یعنی از سریال هیچ چی دریافت نمی کنه ولی به محض اینکه این خط رو از برنامه پاک میکنیم
    On Timer2 Tim
    که سر برگ وقفه تایمر رو معرفی میکنه برنامه به خوبی کار میکنه
    کلا این موضوع مربوط به ساختار خود میکروکنترلر هست و ربطی به IDE که توش برنامه رو می نویسید نداره، حالا میخواد بسکام باشه، کدویژن یا آی ای آر باشه. خود میکروکنترلر چون توانایی Nested Interrupt یا همون خاصیت اجرای چند وقفه رو به صورت همزمان نداره، برای همین مجبورید در ابتدای هر وقفه پرچمی که مربوط به Global Interrupt Enable هست رو غیر فعال کنید و در پایان روتین وقفه دوباره اون رو فعال کنید تا در زمان اجرای روتین وقفه، وقفه دیگری رو اجرا نکنه. اگه سرعت تایمرتون بالا است از روش Polling در همون تایمر روتین وقفه سریال رو اجرا کنید و دیگه وقفه سریال رو از کدتون حذف کنید، به شرطی که زمان بندیتون به هم نخوره و کدتون در وقفه تایمر طولانی نشه.

    موفق باشید.
    اسمایل، تومورو ویل بی وُرس

    دیدگاه


      #3
      پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

      نوشته اصلی توسط ژوپیتر
      برای همین مجبورید در ابتدای هر وقفه پرچمی که مربوط به Global Interrupt Enable هست رو غیر فعال کنید و در پایان روتین وقفه دوباره اون رو فعال کنید
      در خانواده AVR پرچم I در ابتدای ورود به روتین هر وقفه بصورت خودکار صفر می شود و در پایان هر وقفه به وضعیت قبلی خود بر می گردد (در XMEGA چنین موردی برقرار نیست).

      با توجه به محتوای پست اول، به نظر می رسد مشکل آقای رحیمی به دلیل Load بیش از حد CPU برای پاسخگویی به وقفه های مختلف است. برای حل مشکل ابتدا باید به محتوای برنامه توجه کرد که آیا بصورت اصولی نوشته شده و آیا در انجام عملیات، معطلی بی جهتی در روتین وقفه تایمر وجود دارد یا خیر که تا کد موجود نباشد نمی توان در مورد آن اظهار نظر کرد.
      اما به عنوان یک اصل کلی اگر برنامه بصورت اصولی نوشته شده باشد و CPU قادر به پاسخگویی به حاصلضرب تعداد دفعات وقوع وقفه در زمان روتین وقفه نباشد، برای حل مشکل ابتدا باید سطح optimization کامپایلر و در صورت به نتیجه نرسیدن، نوع ابزار برنامه نویسی را برای رسیدن به حداکثر ظرفیت پردازشی تغییر داد.
      در مورد اخیر به احتمال زیاد مشکل ناشی از روش برنامه نویسی است که باید توضیحات بیشتری در مورد آن ارائه شود.
      اوژن: به معنای افکننده و شکست دهنده است
      دانایی، توانایی است-Knowledge is POWER
      برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
      وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
      قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
      اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
      ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

      دیدگاه


        #4
        پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

        با تشکر از همه
        اقای طراح درست میفرمایند
        چون تعداد دستورات من در وقفه یاد هست
        cpu لود میشه و برنامه تو هر 256 سیکل کاری به سر برگ وفقه پرش میکنه
        حالا تو 200 سیکل اگر کارش رو انجام بده بقیه زمان باید برای سریال صرف بشه که فکر کنم خیلی کم هستش
        حالا سوال بعدی من اینه
        توی وقفه تایمر 2 هستیم
        ایا ؟
        ایا در داخل وقفه تایمر 2 وقفه یوزارت اجرا میشه
        یعنی وقفه تایمر ایست کرده به وقفه های دیگر پرشی انجام میگیری ؟
        یا سوال بهتر از اون اولویت های وقفه به چه شکل هستش ؟
        برای اجرای وقفه دیگری در میکرو ایا باید دستورات وقفه قبل تمام بشود ؟
        تونمستم سوالم رو برسونم ؟ ؟
        [move][img width=133 height=100]http://bargiri.persiangig.com/aks/0.306310001356499787_taknaz_ir.gif[/img][/move]

        دیدگاه


          #5
          پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

          در خانواده AVR پرچم I در ابتدای ورود به روتین هر وقفه بصورت خودکار صفر می شود و در پایان هر وقفه به وضعیت قبلی خود بر می گردد (در XMEGA چنین موردی برقرار نیست).
          کاملا درسته، نکته اینجاست که در بعضی موارد دیده شده که با استفاده از بعضی توابع مثلا خواندن یا نوشتن در EEPROM یا همون پورت سریال در وقفه تایمر که نیاز به غیرفعال کردن Global Interrupt دارند، چون در اون تابع بدون در نظر گرفتن محل فراخوانی حالت پرچم Global Interrupt در ابتدا غیرفعال، دستورات لازم انجام و سپس فعال شده، لذا نکته این بود که در استفاده از اونها دقت بشه و در کل زمان اجرای وقفه تایمر حالت پرچم Global Interrupt از حالت غیرفعال خارج نشه.
          اسمایل، تومورو ویل بی وُرس

          دیدگاه


            #6
            پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

            نوشته اصلی توسط حامد رحیمی
            با تشکر از همه
            اقای طراح درست میفرمایند
            چون تعداد دستورات من در وقفه یاد هست
            cpu لود میشه و برنامه تو هر 256 سیکل کاری به سر برگ وفقه پرش میکنه
            حالا تو 200 سیکل اگر کارش رو انجام بده بقیه زمان باید برای سریال صرف بشه که فکر کنم خیلی کم هستش
            حالا سوال بعدی من اینه
            توی وقفه تایمر 2 هستیم
            ایا ؟
            ایا در داخل وقفه تایمر 2 وقفه یوزارت اجرا میشه
            یعنی وقفه تایمر ایست کرده به وقفه های دیگر پرشی انجام میگیری ؟
            یا سوال بهتر از اون اولویت های وقفه به چه شکل هستش ؟
            برای اجرای وقفه دیگری در میکرو ایا باید دستورات وقفه قبل تمام بشود ؟
            تونمستم سوالم رو برسونم ؟ ؟
            از اونجایی که برای Return در AVR تنها یک Stack مونو وجود داره، اگر در زمان اجرای یک وقفه، وقفه های دیگه رو هم فعال کنید مراحل اجرای برنامتون به هم میریزه، به عنوان مثال در زمان حال که در وقفه تایمر هستیم و دستور سوم داره اجرا میشه، در Return Stack شماره ای ذخیره شده که نشان دهنده آدرس برگشت بعد از اجرای تمامی دستورات وقفه تایمر است، مثلا روتین اصلی برنامه است در خط پنجم. در این میان با فعال سازی Global Interrupt برای حالت Nested Interrupt اگر وقفه دریافت در پورت سریال فراخوانی بشه و هنوز اجرای دستورات وقفه تایمر به پایان نرسیده باشه، ناگهان Program Counter از آدرس خط سوم وقفه تایمر(بدون ذخیره کردنش در Return Stack) به خط اول وکتور وقفه دریافت پورت سریال میره و شروع به اجرای دستورات میکنه و دیگه به خط چهارم وقفه تایمر برنمیگرده. اما هنوز هم میشه کاری براش کرد که وقفه تایمر اجرا بشه و همزمان بشه از پورت سریال استفاده کرد، ولی نه با استفاده از وقفه پورت سریال.
            ابتدا زمان کل جرای وقفه تایمر رو به دست بیارید، البته با اضافه کردن همون روش Polling برای خوندن از پورت سریال، لزومی نداره که برای Pulling در تایمر از While استفاده کنید و صبر کنید تا یک بایت دریافت کنید، هرچه زمان اجرای وقفه تایمر کوچکتر باشه، تعداد بایتهای بیشتری رو میتونید از پورت سریال بیرون بکشید.
            نکته مهم: پورت سریال در AVR دارای FIFO نیست و تنها یک بایت رو ذخیره میکنه(آخرین بایت دریافتی)، لذا برای دریافت در پورت سریال از طریق تکنیک Polling در وقفه تایمر، این Baud Rate نیست که اهمیت داره، بلکه زمان مابین ارسال هر یک بایت هست که مهمه. مثلا اگر وقفه تایمر به طور پیش فرض همیشه کمتر از 1 میلی ثانیه طول میکشه تا اجرا بشه، با هر Baud Rate در پورت سریال تنها میتونید مطمئن باشید که با ارسال هر بایت با تاخیر 1 میلی ثانیه در مبدا، اون بایت حتما در بازه 1 میلی ثانیه در وقفه تایمر دریافت میشه و این وسط هیچ اطلاعاتی Overwrite نمیشه یا از دست نمیره.
            اگر هم زمان ارسال هر بایت رو در مبدا بیشتر از 1 میلی ثانیه بکنید، در وقفه تایمر، چون پرچم دریافت در هر بار خوندن صفر میشه، در صورت عدم دریافت بایت جدید، از اون قسمت رد میشه و این چک کردن رو هر دفعه که وقفه تایمر اجرا میشه انجام میده تا یک بایت جدید دریافت کنه.
            اسمایل، تومورو ویل بی وُرس

            دیدگاه


              #7
              پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

              با تشکر از جناب ژوپیتر که اخیرا برای پاسخگویی به دوستان وقت خود را در اختیار قرار می دهند و پست های پربار و خوبی را منتشر می کنند. ساختار Stack (یا با معادل فارسی پشته) در خانواده AVR در SRAM تعریف می شود (به غیر از شماره هایی مانند tiny11 یا tiny12 که Stack دارای محل مشخص و بصورت 3 مرحله ای است). رجیستری به نام Stack pointer همیشه به بالاترین نقطه پشته اشاره می کند که منظور از بالاترین نقطه پشته یا top of stack، محلی در SRAM است که اطلاعات در آن نوشته می شود و با نوشتن اطلاعات مقدار آن بصورت خودکار تغییر می کند و از آدرس های بزرگتر به آدرس های کوچکتر حرکت می کند. بنابراین معمول است که در ابتدای شروع برنامه، آخرین نقطه SRAM به عنوان top of stack در رجیستر Stack pointer نوشته شود که این عمل در کامپایلرهای سطح بالا توسط کامپایلر انجام می شود و در زبان اسمبلی باید توسط برنامه نویس انجام شود. در واقع stack در اکثر شماره های AVR مکان ثابتی نیست و بلکه ناحیه ای در SRAM از نوع LIFO یا Last In First Out است که آخرین اطلاعاتی که در آن نوشته می شود در هنگام خواندن اول بازیابی می شود. با هربار وقوع وقفه و یا call کردن هر زیربرنامه، آدرس بازگشت بصورت خودکار توسط CPU در پشته نوشته می شود و موقع بازگشت از زیر برنامه و یا وقفه، از پشته خوانده و بازیابی می شود.
              با این توضیحات اگر وقفه ای اتفاق بیافتد، آدرس محل بازگشت به روتین اصلی توسط CPU در پشته push می شود و مقدار stack pointer به میزان طول آدرس بازگشت کاهش می یابد. حال اگر به طریقی که در ادامه توضیح داده خواهد شد، وقفه دیگری در بین وقفه اول اتفاق بیافتد، باز هم آدرس بازگشت در پشته توسط CPU ذخیره می شود و بعد از تمام شدن وقفه دوم، به ادامه کار وقفه اول بازگشت می شود و از نظر آدرس بازگشت مشکلی بوجود نخواهد آمد. در واقع تا وقتی که تعداد وقفه ها و استفاده از پشته به حدی نرسد که محتویات آن با اطلاعات دیگر واقع در SRAM تداخل کند، مشکلی در اینکه حتی چندین وقفه هم در داخل یکدیگر به اتفاق بیافتند، بوجود نخواهد آمد.
              در بحث وقوع یک وقفه در بین اجرای یک وقفه دیگر باید به موارد زیر توجه شود:

              1- با شروع اجرای هر وقفه، پرچم I بصورت خودکار صفر می شود و بنابراین وقفه دیگری امکان وقوع نخواهد داشت. اما بصورت نرم افزاری می توان این بیت را یک کرد که در اینصورت سایر وقفه ها هم در بین این وقفه مجوز می یابند تا این وقفه را متوقف کنند. در بسکام این عمل می تواند توسط دستور Enable Interrupts در روتین وقفه انجام می شود. حال اگر به غیر از وقفه در حال اجرا مثلا 4 وقفه دیگر هم داشته باشیم که بخواهیم فقط یکی از آنها امکان وقوع را داشته باشد، باید قبل از یک کردن I، مجوز سایر وقفه هایی که وقوع آنها مورد نظر نیست، توسط خطوط برنامه غیر فعال شوند و در پایان روتین وقفه و قبل از بازگشت هم دوباره به وضعیت سابق بازگردانده شوند. این کار باید بعد از صفر کردن مجدد I انجام شود. بطور کلی عدم وجود اولویت دینامیک در وقفه ها و اجبار به استفاده از روش فوق یک ضعف بزرگ در خانواده AVR است که در سری XMEGA این مشکل با وجود 3 سطح اولویت برطرف شده است (اولویت وقفه ها در AVR از نوع استاتیک است).

              2- در هنگام وقوع یک وقفه، کلیه رجیسترهایی که در سطح قبلی (حلقه اصلی یا وقفه قبلی که درحال پردازش بوده) مورد استفاده قرار می گیرند و از جمله SREG، باید ذخیره سازی شوند. اما اینکه کامپایلر بسکام در صورت ایجاد مجوز وقفه در بین وقفه دیگر آیا این وظیفه را بتواند به درستی انجام دهد یا خیر، از آن اطلاعی ندارم.

              در مورد مشکل آقای رحیمی هم باید زحمت بکشند و توضیح بدهند که چه عملیاتی در وقفه تایمر و سریال مدنظر است تا بر اساس آن بتوان بررسی کرد که آیا می توان با اتخاذ روش هایی نیاز به وقوع وقفه سریال در بین وقفه تایمر را بر طرف کرد و بحث های دیگری مانند روش polling پیشنهادی جناب ژوپیتر که بستگی کامل به نوع صورت مسئله دارد.

              اوژن: به معنای افکننده و شکست دهنده است
              دانایی، توانایی است-Knowledge is POWER
              برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
              وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
              قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
              اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
              ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

              دیدگاه


                #8
                پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

                خیلی ممنون از لطف نظرتون، شما هم مایه افتخار سایت هستید

                چند سال پیش که خیلی با AVR کار میکردم(IAR) مطلبی رو خوندم که در مورد Vector Call و Function Call بود که یکم متفاوت بود، البته نکته های مفیدی رو که شما هم بهشون اشاره کردید رو هم خونده بودم، ولی ایراد کار اینجا بود که من یک حلقه ساده در تایمر نوشتم تا شمارنده رو روی ال سی دی بنویسه، یعنی در وقفه هم تاخیر چشمگیری ایجاد کنه و درست کار میکرد، در پایان وقفه هم باز تایمر رو فعال میکرد و به کارش ادامه میداد. بعد رفتم سراغ اینکه در زمان وقفه تایمر، وقفه دریافت پورت سریال هم کار کنه، در وقفه تایمر Global Interrupt رو فعال کردم و در وقفه دریافت سریال هم نوشتم که بایت دریافت شده رو روی ال سی دی بنویسه.
                انتظار داشتم که در زمانی که در وقفه تایمر روی ال سی دی عدد شمارنده داره هی نوشته میشه، یک لحظه سریع بایت دریافتی نوشته بشه و دوباره همون شمارنده به شمارش ادامه بده و روی ال سی دی بنویسه، ولی این طور نشد.
                با ارسال اولین بایت، بایت دریافتی روی ال سی دی نوشته میشد ولی دیگه خبری از بازگشت به وقفه تایمر نبود، بایت بعدی هم که میفرستادم باز روی ال سی دی مینوشت و کار میکرد ولی دیگه تایمر از کار افتاده بود.
                این باعث شک من به اطلاعات داخل دیتاشیت شد :eek:
                دفعه بعد در مورد SPM و Self-Programming این اتفاق افتاد که داشتم Boot Loader برای پورت سریال مینوشتم و متوجه شدم که اطلاعات داخل دیتاشیت رو هر کاری میکنم کار نمیکنه. نوشته که به چه ترتیبی باید مراحل انجام بشه، هرکاری بگین کردم، جواب نداد، بعد جای دو قسمت رو جابه جا کردم، کارکرد و الآن تقریبا 3 ساله که کار میکنه و از Mega16 تا 2561 رو ازش جواب گرفتم. بازم اطلاعات دیتاشیت :eek:


                در جاهایی خوندم که Interrupt ها در AVR (همونطور که شما هم بهش اشاره کردید) دارای اولویت پذیری نیستند، من در زمانی که با بوت لودر کار میکردم، چون نیاز به پورت سریال داشتم مجبور شدم که وکتور پورت سریال رو برای بوت لودر جا به جا کنم تا Vector Call اون از 4 کیلوبایت آخر فلش، یعنی همون محل بوتلودر باشه، در زمانی هم که لازم نبود، خود بوتلودر وکتور رو برمیگردوند سرجاش که برنامه ازش استفاده کنه، اونجا بود که متوجه شدم، وقفه ها در Vector Table بر اساس ترتیب دارای اولویت هستند، یعنی مثلا ریست Vector که در ابتدای جدوله و آدرسش صفره از همه اولویتش بالاتره و هرچه به پایین جدول میریم، اولویتها میاد پایین، با جابه جا کردن وکتورها میشه اولویتهای هر وقفه رو هم تغییر داد، ولی نمیشه مثلا دو وقفه دارای یک اولویت یکسان باشند. همونطور که گفتم منهم مطالبی که شما اشاره کردید رو مطالعه کرده بودم، ولی مثل اینکه یا مطالب قدیمی بوده یا تکنیک جدیدی در کامپایلرها ایجاد شده، خلاصه آی دونت نو :icon_razz:

                مثلا دکتر Margush در مورد وقفه ها در مگا 16 میگه اولویت بندی هست، یکی دیگه میگه نیست، والا ما که نفهمیدیم چیشد، ولی تست کردیم بود

                فقط این نیست، سوتی های گنده ای از کمپانیهای غولی مثل STMicroelectronics دیدم که باورم نمیشد ولی واقعا سوتی بود، در حدی که مدیرعامل مجبور شد ازشون درخواست یک دیتاشیت درست بکنه و ایرادات رو هم گزارش کردن بهشون. وقتی Division مربوطه مطلع شد، همه شاخاشون زده بود بیرون ولی سعی میکردن به روی خودشون نیارن. خوب بالاخره آدمه دیگه، اشتباه میکنه، ما هم مستثنا نیستیم.
                خلاصه اینجوری هم هست، موفق باشید.
                اسمایل، تومورو ویل بی وُرس

                دیدگاه


                  #9
                  پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

                  خیلی ممنون اطلا عات خوبی به دستم اومد اطلا عاتی که میدونستم ولی انقدر ناقص بود که تو کارام مشکل پیش میومد من برنامه رو اپلود میکنم درسته مبتدیانه هستش
                  ولی شاید راهی ایده ای نظری را جع بهش داشته باشین قراره برنامه با استفاده از کد های مخصوصی 6 تا رقم 0 تا 1023 از ماژول hmtr دریافت کنه و روی 6 تا پایه pwm درست کنه pwm مخصوص سرو متور sg5010 البته دیتا شیت معتبری هم نتونستم برای این سروو پیدا کنم
                  فقط زمان پهنای پالس دقیق این سرور رو نیاز دارم اگه دارید ممنون میشم :cry: اپلود کنید
                  جمعا 3 تا فایل هستش که اپلود کردم
                  دیتا شیت سروو متور فایل ارسال دیتا فایل دریافت دیتا (هگز )
                  فایل های پیوست شده
                  [move][img width=133 height=100]http://bargiri.persiangig.com/aks/0.306310001356499787_taknaz_ir.gif[/img][/move]

                  دیدگاه


                    #10
                    پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

                    نوشته اصلی توسط ژوپیتر
                    مثلا دکتر Margush در مورد وقفه ها در مگا 16 میگه اولویت بندی هست، یکی دیگه میگه نیست، والا ما که نفهمیدیم چیشد
                    اولویت در وقفه های AVR وجود دارد، اما از نوع استاتیک است. به این معنی که اگر دو یا چند وقفه با هم درخواست شوند، به وقفه ای که دارای آدرس بردار وقفه کوچکتر است پاسخ داده می شود. اما اولویت به شکلی که در 8051 یا XMEGA وجود دارد که دربین اجرای یک وقفه با اولویت پائین تر، اولویت بالاتر آن را متوقف می کند، در AVR وجود ندارد و باید با همان شیوه ای که در پست قبلی اشاره شد با این مسئله برخورد شود.

                    نوشته اصلی توسط حامد رحیمی
                    ولی شاید راهی ایده ای نظری را جع بهش داشته باشین قراره برنامه با استفاده از کد های مخصوصی 6 تا رقم 0 تا 1023 از ماژول hmtr دریافت کنه و روی 6 تا پایه pwm درست کنه )
                    با یک نگاه کلی به برنامه شما مشخص می شود که به ازای هر 256 کلاک که فرکانس آن هم 16 مگاهرتز است، وقفه ای ایجاد شده که در این وقفه، 5 سیگنال PWM بصورت نرم افزاری تولید شده است. روش بکار گرفته شده در برنامه برای تولید PWM موجب زیر بار رفتن بیجهت CPU شده است که جای اصلاح فراوان دارد و اصولا نیازی به وقفه تایمر برای انجام این عملیات نیست. بلکه می توان یک تایمر را با کلاک مناسب به کار انداخت و در حلقه اصلی بصورت دائمی مقدار آن را قرائت کرد و با set point هر کانال PWM مقایسه و خروجی ها را بر اساس آن تغییر داد.
                    اوژن: به معنای افکننده و شکست دهنده است
                    دانایی، توانایی است-Knowledge is POWER
                    برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                    وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                    قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                    اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                    ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                    دیدگاه


                      #11
                      پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

                      نوشته اصلی توسط طراح

                      در بحث وقوع یک وقفه در بین اجرای یک وقفه دیگر باید به موارد زیر توجه شود:

                      1- با شروع اجرای هر وقفه، پرچم I بصورت خودکار صفر می شود و بنابراین وقفه دیگری امکان وقوع نخواهد داشت. اما بصورت نرم افزاری می توان این بیت را یک کرد که در اینصورت سایر وقفه ها هم در بین این وقفه مجوز می یابند تا این وقفه را متوقف کنند. در بسکام این عمل می تواند توسط دستور Enable Interrupts در روتین وقفه انجام می شود. حال اگر به غیر از وقفه در حال اجرا مثلا 4 وقفه دیگر هم داشته باشیم که بخواهیم فقط یکی از آنها امکان وقوع را داشته باشد، باید قبل از یک کردن I، مجوز سایر وقفه هایی که وقوع آنها مورد نظر نیست، توسط خطوط برنامه غیر فعال شوند و در پایان روتین وقفه و قبل از بازگشت هم دوباره به وضعیت سابق بازگردانده شوند. این کار باید بعد از صفر کردن مجدد I انجام شود. بطور کلی عدم وجود اولویت دینامیک در وقفه ها و اجبار به استفاده از روش فوق یک ضعف بزرگ در خانواده AVR است که در سری XMEGA این مشکل با وجود 3 سطح اولویت برطرف شده است (اولویت وقفه ها در AVR از نوع استاتیک است).

                      2- در هنگام وقوع یک وقفه، کلیه رجیسترهایی که در سطح قبلی (حلقه اصلی یا وقفه قبلی که درحال پردازش بوده) مورد استفاده قرار می گیرند و از جمله SREG، باید ذخیره سازی شوند. اما اینکه کامپایلر بسکام در صورت ایجاد مجوز وقفه در بین وقفه دیگر آیا این وظیفه را بتواند به درستی انجام دهد یا خیر، از آن اطلاعی ندارم.
                      با تشکر از استاد کی نژاد، جسارتاً یک نکته کوچیک رو هم بنده میخوام بهش اشاره کنم.
                      در بحث فعال سازی وقفه های تو در تو مهمترین نکته ای که باید رعایت شود و بدان اشاره نشده این است که چنانچه میخواهید داخل یک روتین وقفه، وقفه سراسری (و وقفه های دیگر)را فعال نمائید قبل از آن حتماً وقفه مربوط به تجهیز جانبی که اکنون در روتین وقفه آن به سر میبریم غیر فعال گردد. در غیر این صورت به احتمال زیاد با چیزی شبیه به یک فاجعه روبرو خواهیم بود. یعنی فوران کردن STACK . البته این مشکل تا حدودی به نوع تحریک وقفه بستگی دارد.
                      در واقع این امر زمانی که عامل (تحریک) وقفه به طور پیوسته و دائم و با فواصل زمانی کوتاهتر از مدت انجام دستورات داخل روتین وقفه رخ دهد به وقوع پیوسته و موجب پر شدن STACK و به اصطلاح فوران آن خواهد شد.
                      مهمترین علتی که کمپانی سازنده و البته طراحان کامپایلر کاربران را از فعال کردن مجدد وقفه سراسری در داخل یک روتین وقفه منع میکنند همین مسئله است. وگرنه در صورت رعایت این موضوع میکروکنترلر های AVR به خوبی قابلیت اجرای وقفه تو در تو رادارند.

                      دیدگاه


                        #12
                        پاسخ : تداخل وقفه سریال با وقفه تایمر در بیسکام

                        نوشته اصلی توسط طراح
                        با تشکر از جناب ژوپیتر که اخیرا برای پاسخگویی به دوستان وقت خود را در اختیار قرار می دهند و پست های پربار و خوبی را منتشر می کنند. ساختار Stack (یا با معادل فارسی پشته) در خانواده AVR در SRAM تعریف می شود (به غیر از شماره هایی مانند tiny11 یا tiny12 که Stack دارای محل مشخص و بصورت 3 مرحله ای است). رجیستری به نام Stack pointer همیشه به بالاترین نقطه پشته اشاره می کند که منظور از بالاترین نقطه پشته یا top of stack، محلی در SRAM است که اطلاعات در آن نوشته می شود و با نوشتن اطلاعات مقدار آن بصورت خودکار تغییر می کند و از آدرس های بزرگتر به آدرس های کوچکتر حرکت می کند. بنابراین معمول است که در ابتدای شروع برنامه، آخرین نقطه SRAM به عنوان top of stack در رجیستر Stack pointer نوشته شود که این عمل در کامپایلرهای سطح بالا توسط کامپایلر انجام می شود و در زبان اسمبلی باید توسط برنامه نویس انجام شود. در واقع stack در اکثر شماره های AVR مکان ثابتی نیست و بلکه ناحیه ای در SRAM از نوع LIFO یا Last In First Out است که آخرین اطلاعاتی که در آن نوشته می شود در هنگام خواندن اول بازیابی می شود. با هربار وقوع وقفه و یا call کردن هر زیربرنامه، آدرس بازگشت بصورت خودکار توسط CPU در پشته نوشته می شود و موقع بازگشت از زیر برنامه و یا وقفه، از پشته خوانده و بازیابی می شود.
                        با این توضیحات اگر وقفه ای اتفاق بیافتد، آدرس محل بازگشت به روتین اصلی توسط CPU در پشته push می شود و مقدار stack pointer به میزان طول آدرس بازگشت کاهش می یابد. حال اگر به طریقی که در ادامه توضیح داده خواهد شد، وقفه دیگری در بین وقفه اول اتفاق بیافتد، باز هم آدرس بازگشت در پشته توسط CPU ذخیره می شود و بعد از تمام شدن وقفه دوم، به ادامه کار وقفه اول بازگشت می شود و از نظر آدرس بازگشت مشکلی بوجود نخواهد آمد. در واقع تا وقتی که تعداد وقفه ها و استفاده از پشته به حدی نرسد که محتویات آن با اطلاعات دیگر واقع در SRAM تداخل کند، مشکلی در اینکه حتی چندین وقفه هم در داخل یکدیگر به اتفاق بیافتند، بوجود نخواهد آمد.
                        در بحث وقوع یک وقفه در بین اجرای یک وقفه دیگر باید به موارد زیر توجه شود:

                        1- با شروع اجرای هر وقفه، پرچم I بصورت خودکار صفر می شود و بنابراین وقفه دیگری امکان وقوع نخواهد داشت. اما بصورت نرم افزاری می توان این بیت را یک کرد که در اینصورت سایر وقفه ها هم در بین این وقفه مجوز می یابند تا این وقفه را متوقف کنند. در بسکام این عمل می تواند توسط دستور Enable Interrupts در روتین وقفه انجام می شود. حال اگر به غیر از وقفه در حال اجرا مثلا 4 وقفه دیگر هم داشته باشیم که بخواهیم فقط یکی از آنها امکان وقوع را داشته باشد، باید قبل از یک کردن I، مجوز سایر وقفه هایی که وقوع آنها مورد نظر نیست، توسط خطوط برنامه غیر فعال شوند و در پایان روتین وقفه و قبل از بازگشت هم دوباره به وضعیت سابق بازگردانده شوند. این کار باید بعد از صفر کردن مجدد I انجام شود. بطور کلی عدم وجود اولویت دینامیک در وقفه ها و اجبار به استفاده از روش فوق یک ضعف بزرگ در خانواده AVR است که در سری XMEGA این مشکل با وجود 3 سطح اولویت برطرف شده است (اولویت وقفه ها در AVR از نوع استاتیک است).

                        2- در هنگام وقوع یک وقفه، کلیه رجیسترهایی که در سطح قبلی (حلقه اصلی یا وقفه قبلی که درحال پردازش بوده) مورد استفاده قرار می گیرند و از جمله SREG، باید ذخیره سازی شوند. اما اینکه کامپایلر بسکام در صورت ایجاد مجوز وقفه در بین وقفه دیگر آیا این وظیفه را بتواند به درستی انجام دهد یا خیر، از آن اطلاعی ندارم.

                        در مورد مشکل آقای رحیمی هم باید زحمت بکشند و توضیح بدهند که چه عملیاتی در وقفه تایمر و سریال مدنظر است تا بر اساس آن بتوان بررسی کرد که آیا می توان با اتخاذ روش هایی نیاز به وقوع وقفه سریال در بین وقفه تایمر را بر طرف کرد و بحث های دیگری مانند روش polling پیشنهادی جناب ژوپیتر که بستگی کامل به نوع صورت مسئله دارد.
                        ُبا سلام و تشکر از جناب کی نژاد
                        میشه راجب پشته بیشتر توضیح بدین ؟ درمورد توابع تو در تو ... چون منم یک برنامه نوشته بودم که روال های تو در تو اگه زیاد میشد برنامه به اون صورت که باید پیش میرفت ، نرفت و مجبور شدم کلا بیشتر از دو تابع تو در تو استفاده نکنم ...
                        چطور میشه به صورت دقیق کنترل کرد و محاسبه کرد که تا چقد محدود هستیم در روال های تو در تو که میکرو هنگ نکنه ،و به روال ها درست بازگرده ؟

                        با تشکر

                        دیدگاه

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