اینتراپت یا وقفه در میکروکنترلر AVR – جلسه پنجم

وقفه در میکروکنترلر AVR

وقفه در میکروکنترلر AVR

در جلسه گذشته به آموزش راه اندازی lcd کاراکتری با avr پرداختیم و حالا نوبت وقفه هاست!

وقفه در میکروکنترلر AVR یکی از واحد های مفید و بسیار کاربردیه که قراره این جلسه بهش بپردازیم.

وقفه در میکروکنترلر چیست؟

یادتونه در جلسه اول و معرفی میکروکنترلر atmega32 گفتم که جلوی هر پایه بجز مشخص کردن پورت و شماره اون کاربرد های دیگه اونهارو هم نوشته ؟

یکی از این کاربرد ها اینتراپت یا وقفه نام داره.

 

پایه های میکورکنترلر ATMEGA16

interrupt در میکرو های atmega16 و Atmega32 بر روی پایه های PD1(INT0) و PD2(INT1) و PB2(INT2) وجود دارد. interrupt در میکروهای دیگر مانند atmega128 تا 8 پایه وجود دارد!(به دیتاشیت مراجعه کنید.)

اما با اینتراپت چه امکانی برای ما فراهم میشه و چه کاریردی داره ؟

فرض کنید کلیدی رو به پایه ی INT0 وصل کردیم و وقتی که کلید وصل شد میخوایم یک LED رو روشن کنیم .

راه اولی که به ذهن همه میرسه اینه که مقدار کلید رو بخونیم , و مثلا بعنوان شرط در یک if قرار بدیم و بعداز زده شدن کلید ، برنامه روشن شدن led رو اجرا کنیم.

 

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

اینتراپت اینجا وارد کار میشه و یک راه بهتر رو پیش پای ما میزاره .

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

با این روش میتونیم برناممون که مثلا صد خط و چند عملکرد در یک سیستم هستش (برنامه اصلی) رو با میکرو انجام بدیم و هر موقع که کلید زده شد برنامه ی روشن شدن led هم شروع به کار کنه.(زیر برنامه)

کل کاری که قراره اینتراپت یا وقفه در میکروکنترلر AVR انجام بده همینه 🙂

 

اینتراپت در avr انواع مختلفی داره و این 3 پایه ای که من ازشون نام بردم اینتراپت های خارجی AVR هستن و ما هم این جلسه فقط به همین اینتراپت های خارجی کار داریم و بقیشو جلسات آینده میگیم.

انواع اینتراپت ها در میکروکنترلر atmega 32 (برای هر میکرویی میتونید به دیتاشیت مراجعه کنید.)

اولویت وقفه ها در atmega

توجه کنید که وقفه ها طبق همین لیست دارای الویت هستند! یعنی اگر همزمان 2 وقفه اجرا شود ، ابتدا وقفه با اولویت بالاتر شروع به کار میکند و میکرو پس از آن به سراغ وقفه بعدی خواهد رفت.(فعلا فقط الویت های وقفه های خارجی را به خاطر بسپارید.)

 

حالت های بررسی وقفه در میکروکنترلر AVR

برای اینکه interrupt در میکرو فعال بشه ، میکرو پایه ها رو  بررسی میکنه و طبق برنامه ای که ما مینویسیم اگر تغییری رخ داد وارد زیربرنامه وقفه میشه.

برای این کار 4 مد یا حالت اینتراپت در avr داریم.(این مد هارو از طریق کدویزارد تنظیم میکنیم)

 

مد low level:

در این مد ، زمانی وقفه شروع به فعالیت میکنه که پایه ی مورد نظر صفر (0v) بشه.

 

مد falling edge :

در این مد وقفه زمانی اتفاق میوفته که پایه از 5 ولت به 0 تغییر حالت میده.(در لحظه ی تغییر سطح صورت میگیره)

 

falling edge در اینتراپت

مد rising edge :

در این مد وقفه زمانی اتفاق میوفته که پایه از 0 ولت به 5 تغییر حالت میده.(دقیقا در لحظه ی  تغییر سطح صورت میگیره)

 

rising edge اینتراپت

مد any change :

در این مد هر نوع تغییر سطح منطقی ، اعم از صفر به یک(5ولت) یا از یک به صفر باعث ایجاد وقفه در برنامه میکند. این حالت به اصطلاح حساس به لبه هم گفته میشه.

 

پایه های int0 و int1 در atmega 16 و atmega 32هر 4 حالت بالا رو شامل میشن اما برای int2 حالت های 2 و 3 فقط قابل تعریف کردنه.

 

آموزش وقفه در کدویژن

وقفه در کدویژن رو حالا بیاین امتحان کنیم و بریم سراغ چند تا مثال!

مثال یک :

برنامه ای بنویسید که زمانی پایه ی int0 صفر شد(پایه ی 16) ، بر روی صفحه ی lcd کلمه ی Done! نوشته شود.

 

یک پروژه ایجاد میکنیم مثل جلسات قبل آموزش AVR ، و اینبار در کدویزارد تنظیمات رو به شکل زیر انجام میدیم. (زبانه ی External interrupt)

تنظیم اینتراپت در کدویزارد

قراره از lcd هم استفاده کنیم که جلسه قبل یادگرفتیم ازش استفاده کنیم : آموزش راه اندازی lcd به avr

LCD رو هم میتونید به هر پورتی که تمایل دارین وصل کنین ، من به پورت b متصل میکنم.

تنظیم lcd در کدویزارد

بعد از Generate کردن کد ، میبینید که در ابتدای برنامه یک تابع به شکل زیر ایجاد شده:

 

در بین آکولاد های این تابع هر دستوری که بنویسیم اجرا نمیشه تا زمانی که یک وقفه ایجاد بشه(در این برنامه باید پایه ی int0 مقدارش صفر بشه تا وقفه ایجاد بشه).اون موقع میکروکنترلر حلقه ی while رو بیخیال میشه و میاد این حلقه رو اجرا میکنه.

در نتیجه کد به شکل زیر خواهد بود :

 

و در پروتئوس هم باید طبق شکل زیر مدار رو ببندید:

اینتراپت در پروتئوس

چون قرار نیست کار دیگه ای انجام بدیم ، حلقه ی while نیاز به کدنویسی نداره!

برای آوردن کلید فشاری در پروتئوس باید button سرچ کنید و برای lcd باید lm016 سرچ کنید .

 

مثال 2 : برنامه ای بنویسید که به ازای لبه ی بالا رونده در وقفه ی شماره 2 ولتاژ پایه ی PA0 که یک led به اون متصل شده معکوس شود.

 

جواب :

int2 کدویزارد

و پورت A2 :

codewizard porta2

کد رو generate میکنیم و در تابع اینتراپت معکوس کردن پایه رو برای avr تعریف میکنیم، کد به شکل زیر در می آد :

 

 

دانلود کد + شبیه سازی

 

رجیستر وقفه ها در میکروکنترلر AVR

تا اینجا تونستیم راه اندازی وقفه ها در میکروکنترلر AVR رو از طریق کدویزارد انجام بدیم و حالا وقتشه که با رجیستری ها آشنا بشیم .

ریجستر SREG

زمانی که ما میکرو در حالت عادی خودش داره کار میکنه  بصورت پیش فرض به اینکه وقفه اتفاق میوفته یا نمیوفته کاری نداره . با تغییر و یک کردن بیت هفتم رجیستر status register ، به cpu میگیم که وقفه رو فعال کن ! یعنی به شکل سراری وقفه هارو فعال میکنیم.

 

ریجستر SREG وقفه ها

این اتفاقیه که برای رجیستر status register  یا SREG میوفته ، اما چطوری میتونیم اینکارو در برنامه انجام بدیم ؟با نوشتن کد زیر:

و با کد زیر هم میشه اون رو غیرفعال کرد :

 

ریجستر GICR

GICR register avr اینتراپت

تو این ریجستر با یک کردن هرکدوم از 3 بیت آخر یکی از اینتراپت های int0,int1,int2 رو میتونیم فعال کنیم.

بیت 5 (INT2 ) : با یک کردن این بیت وقفه 2 فعال میشه.

بیت 6 (INT0 ) : با یک کردن این بیت وقفه 0 فعال میشه.

بیت 7 (INT1 ) : با یک کردن این بیت وقفه 1 فعال میشه.

 

در برنامه میتونیم به شکل زیر به رجیستر فرمان بدیم :

که در اینجا int2 رو فعال کردیم.

 

ریجستر GIFR

gifr-register-avr

اگر یک وقفه در میکروکنترلر AVR رو با GICR و وقفه های سراسری رو با SREG فعال کرده باشیم و اون پایه مورد نظر تحریک شده باشه و وقفه اتفاق افتاده باشه بیت مربوط به اون پایه در این ریجستر یک میشه و درخواست اجرای وقفه رو میده(اجرا نمیکنه فقط درخواستشو میده!) و به تابع تعریف شده (تابع زیربرنامه) پرش میکنه.

برای این که این قدرت تصمیم گیری رو به این ریجستر بدیم باید بیت های لازم ریجستر رو یک کنیم.

مثلا در مثال بالا از INT2 استفاده کردیم ، برای این رجیستر هم باید بیت مربوط به INT2 رو یک کنیم.(بیت 5)

 

رجیستر MCUCR

در این رجیستر به 4 بیت 0 تا 3 کار داریم :

این ریجستر برا دو وقفه صفر و یک  کاربرد داره و در وقفه ها وظیفه تریگ شدن پایه هارو بر عهده داره، یعنی مشخص میکنه که کدوم یکی از مد های Rising و falling و low level و any change رو فعال کنیم برای پایه ها.

برای تریگ کردن پایه ی INT0 باید طبق جدول زیر عمل کنیم :

MCUCR-register-int0-avr

برای تریگ کردن پایه ی INT1 باید طبق جدول زیر عمل کنیم :

MCUCR-register-int1-avr

 

رجیستر MCUCSR

و آخرین رجیستر وقفه در میکروکنترلر AVR که مشابه رجیستر قبلی هستش ، با این تفاوت که مربوط به INT2 هستش. (همونطور که بالا گفتم این پایه 2 حالت داره، صفر و یک منطقی و شامل 2حالت دیگه برای تحریک نمیشه.)

MCUCSR-register-avr-int2

در این رجیستر اگه بیت 6 (ISC2) این ریجستر رو صفر کنی با صفر منطقی (falling ) فعال میشه.
اگه بیت 6 (ISC2) این ریجستر رو یک کنی با یک منطقی (rising ) فعال میشه.

 

متل پروژه دوم همین مطلب که مقدار 1 داره و با یک منطقی وقفه فعال میشه (rising) :

 

اینتراپت یا وقفه در میکروکنترلر AVR هم به پایان رسید. امیدوارم کاملا با واحد اینتراپت در Avr آشنا شده باشید.

 

حمیدرضا مودت

یک مهندس الکترونیک ، علاقه مند به یاد دادن و یاد گرفتن پیرامون دانش برق و الکترونیک

مطالب مرتبط

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *