اولویت وقفه در AVR
اولویت وقفه ها(Interrupt) در AVR بستگی به آدرس آنها در حافظه دارد به طوری که هر وقفه ای که آدرس پایین تری داشته باشد اولویت بالاتری در اجرا دارد. جدول زیر آدرس بردار وقفه ها برای میکروکنترلر MEGA32 میباشد.
وقفه های خارجی:
وقفه های خارجی از طریق INT0, INT1 …… اعمال میشوند حتی در صورتی که پایه های مربوط به این وقفه ها به عنوان خروجی کانفیگ شده باشند وقفه ها اجرا میشوند که از این قابلیت میتوان به عنوان ایجاد وقفه نرم افزاری استفاده کرد.
وقفه های خارجی با لبه پایین رونده یا لبه بالا رونده یا تغییر سطح ولتاژ روی پایه وقفه ایجاد میشوند. وقفه سطح ولتاژ پایین برای INT0/INT1 و وقفه لبه برای INT2 حتی در زمانی که میکروکنترلر در حالت SLEEP میباشد و کلاک I/O ها قطع است کار میکنند و برای بیدار کردن میکروکنترلر از حالت SLEEP میتوانند استفاده شوند.
رجیستر MCUCR:
در صورتی که وقفه لبه یا تغییر سطح انتخاب شده باشد، یک پالس به طول حداقل یک کلاک میکروکنترلر وقفه را ایجاد میکند و در صورتی که طول پالس روی پایه وقفه کمتر از یک کلاک میکروکنترلر باشد وقفه ایجاد نخواهد شد. و درصورتی که وقفه سطح ولتاژ پایین انتخاب شده باشد باید تا زمان اتمام اجرای دستورالعمل جاری توسط CPU، سطح ولتاژ پایین حفظ شود تا وقفه ایجاد شود.
بیت 0 و 1 برای انتخاب نوع وقفه پایه INT0 و بیت 2 و 3 برای انتخاب نوع وقفه INT1 مطابق جدول زیر استفاده میشوند.
رجیستر MCUCSR:
اگر بیت 6 از این رجیستر 0 باشد وقفه لبه پایین رونده روی پایه INT2 به صورت آسنکرون فعال میشود و اگر مقدار 1 در این رجیستر نوشته شود لبه بالارونده وقفه ایجاد میکند. حداقل طول پالس روی این پایه برای ایجاد وقفه 50 نانو ثانیه میباشد. زمانی که مقدار این بیت تغییر داده میشود یک وقفه تولید میشود بنابراین ابتدا باید وقفه INT2 در رجیستر GICR غیرفعال شود سپس این بیت تغییر داده شده و پرچم وقفه پاک شود سپس مجددا وقفه INT2 در رجیستر GICR فعال شود.
رجیستر GICR:
بیت های 5، 6 و 7 این رجیستر جهت فعال سازی وقفه های INT2, INT0 و INT1 میباشند که با نوشتن 1 در هر بیت وقفه متناظر با آن فعال میشود.
رجیستر GIFR:
بیت های 5، 6 و 7 این رجیستر نشان دهنده وضعیت وقفه های INT0, INT2 و INT1 میباشند در صورت فعال شدن هر کدام از وقفه ها بیت متناظر با آن در این رجیستر 1 میشود. پرچم وقفه با اجرای روتین وقفه پاک میشود. همچنین با نوشتن 1 در این بیت ها پرچم وقفه پاک میشود.
پاسخ به چند سوال متداول درباره وقفه ها در AVR:
سوال: آیا بین وقفه های AVR اولویتی وجود دارد؟
پاسخ: در AVR وقفه هایی که دارای آدرس بردار کوچکتری در حافظه flash هستند نسبت به وقفه های دارای آدرس بردار وقفه بزرگتر، در شرایط درخواست همزمان دارای اولویت هستند. بنابراین اگر دو وقفه بصورت همزمان درخواست شوند، وقفه ای پذیرفته می شود که بردار وقفه آن دارای آدرس کوچکتری در حافظه flash باشد. اما تعیین اولویت بصورتی که در برخی میکروکنترلرهای دیگر مانند XMEGA قابل تعریف است در AVR وجود ندارد.
سوال: آیا امکان پذیرش وقفه در وقفه وجود دارد؟
پاسخ: در AVR با پذیرش هر وقفه، بیت I در SREG که مجوز سراسری وقفه است بصورت خودکار صفر می شود و در پایان وقفه مجددا یک می شود که در این شرایط پذیرش هر وقفه جدید تا پایان وقفه جاری ممکن نیست. اما با اجرای دستورالعمل ها می توان بیت I را در روتین وقفه بصورت نرم افزاری یک کرد که در این صورت امکان پذیرش وقفه دیگری در هنگام اجرای وقفه جاری وجود دارد. نکته قابل ذکر این است که بعد از پذیرش وقفه جدید و اتمام روتین آن، اجرای روتین وقفه جاری ادامه پیدا خواهد کرد.
سوال: اگر در هنگام اجرای یک وقفه، تقاضای وقفه دیگری ایجاد شود آیا ممکن است این تقاضا توسط CPU دیده نشود و به اصطلاح وقفه از بین برود؟
پاسخ: وقفه ها در AVR بصورت کلی دو دسته هستند. دسته اول که اکثریت وقفه ها را تشکیل می دهند دارای یک پرچم (Flag) درخواست وقفه هستند. حتی در صورتی که وقفه ای در حال اجرا باشد، درخواست این نوع وقفه ها بعد از اتمام وقفه جاری به دلیل یک ماندن پرچم وقفه، از طرف CPU دیده می شود و تقاضای وقفه به اصطلاح از بین نمی رود. اما نوع دومی از درخواست وقفه هم مانند وقفه خارجی پورت ها در سطح Low وجود دارد که علیرغم وجود پرچم درخواست وقفه برای وقفه های خارجی، اما در صورت تنظیم منبع درخواست وقفه روی سطح Low تاثیری روی پرچم وقفه ایجاد نمی شود. بنابراین اگر در هنگام درخواست این نوع وقفه ها وقفه دیگری در حال اجرا باشد و تا قبل از پایان آن، درخواست وقفه از طرف منبع آن متوقف شود (مثلا برای سطح Low پین به وضعیت High بر گردد) در اینصورت چنین در خواستی از طرف CPU دیده نخواهد شد و به اصطلاح وقفه از بین می رود. این مورد البته جنبه استثنا دارد و فقط شامل وقفه هایی است که پرچم وقفه برای آنها عمل نمی کند.
سوال: آیا ممکن است به دلیل درخواست های مکرر چند منبع وقفه، برخی از آنها اصلا پذیرفته نشوند؟
پاسخ: در شرایطی پاسخ به این سوال می تواند مثبت باشد. اگر وقفه ای با آدرس بردار کوچکتر در حافظه flash به صورت مکرر درخواست شود و با برگشت از روتین وقفه پرچم وقفه یک باشد و بلافاصله وقفه دیگری اجرا شود، در این شرایط وقفه های با آدرس بردار بزرگتر امکان پذیرش از طرف CPU را نخواهند داشت.
سوال: آیا وقفه های پشت سر هم می تواند اجرای برنامه در حلقه اصلی را متوقف کند؟
پاسخ: بعد از بازگشت از هر وقفه، CPU حداقل یک دستورالعمل اسمبلی را اجرا می کند. بنابراین اجرای وقفه ها بصورت مکرر و پشت سرهم علیرغم اینکه می تواند باعث کند شدن اجرای حلقه اصلی شود اما نمی تواند اجرای آن را متوقف کند.
منبع: @KnowledgePlus