آموزش وقفه در میکروکنترلرهای AVR وقفه خارجی در ATmega128A

توسط | 11 دی, 1398 | میکروکنترلر | 18 دیدگاه ها

تعریف وقفه (Interrupt)، کاربرد وقفه، منابع تحریک وقفه، روتین وقفه یا روتین سرویس وقفه (ISR – Interrupt Service Routine)، بردار وقفه و اولویت وقفه ها، مراحل وقفه در AVR، وقفه های خارجی در AVR، رجیسترهای وقفۀ خارجی، بیت I در SREG (رجیستر وضعیت)، تمرین وقفۀ خارجی
وقفه-خارجی-avr

وقفه چیست؟ وقفه ها در AVR چگونه اتفاق می افتند؟ روتین یا روال وقفه چیست؟ وقفۀ خارجی چیست؟ بردار وقفه به چه معناست؟ اولویت وقفه ها به چه صورت است؟ سینتکس نوشتاری روتین وقفه چگونه است؟ چگونه وقفۀ خارجی را راه اندازی کنیم؟ برای دریافتن پاسخ این سوالات با ما همراه باشید.

وقفه یکی از قابلیت های مهم میکروکنترلرهاست. استفاده از وقفه ها در یک میکروکنترلر یک امر ضروری است زیرا این امکان را فراهم می کنند که میکروکنترلر بتواند با وجود اطلاع یافتن از مجموعه ای از اتفاقات در داخل و یا خارج از میکروکنترلر، دستورها را به صورت real time اجرا کند. این امر یکی از فاکتورهای افزایش کارایی و سرعت اجرای برنامه است. در این نوشته وقفه و بلوک وقفه های خارجی را مورد بررسی قرار می دهیم. ابتدا نیاز است بدانیم وقفه چیست، چگونه به وجود می آید، روتین (روال) وقفه چیست و بدانیم هنگام روی دادن آن و در مراحل اجرای آن چه کارهایی در میکروکنترلر انجام می شود.

فیلم آموزش وقفه در STM32                    (فیلم آموزش ARM STM32 مقدماتی)

فیلم آموزش وقفه خارجی در AVR              (فیلم آموزش AVR مقدماتی)

فیلم آموزش وقفه در آردوینو                       (فیلم آموزش آردوینو مقدماتی)

تعریف وقفه (Interrupt)

یک فرایند است که طی آن میکروکنترلر از وقوع یک اتفاق اطلاع پیدا می کند به طوری که دیگر لازم نیست cpu دائماً وقوع آن اتفاق را بررسی کند. وقفه یک امکان سخت افزاری است و هنگامی  که فعال شود، cpu بدون این که درگیر بررسی وقوع اتفاقی باشد، می تواند از وقوع آن اتفاق اطلاع پیدا کند. بنابراین در حالی که cpu در حال اجرای دستورهای دیگر است، به صورت موازی از وقوع اتفاقات دیگر نیز اطلاع پیدا می کند و این کار به real time بودن برنامه کمک می کند.

کاربرد وقفه

هرگاه بخواهیم میکروکنترلر بدون بررسی دائم وقوع یک اتفاق، با وقوع آن اتفاق یک برنامه را اجرا کند از وقفه استفاده می کنیم. این اتفاق می تواند تغییر سطح یک ولتاژ ورودی به پایه های خاصی از میکروکنترلر، سرریز یک تایمر، اتمام تبدیل ADC یا … باشد. میکروکنترلر همواره در حال اجرای برنامۀ نوشته شده در حلقه بی نهایت while است. هرگاه وقفه ای اتفاق بیفتد، برنامۀ در حال اجرا را رها می کند و برنامۀ نوشته شده در روتین وقفه را اجرا می کند. پس از اتمام آن روتین، برنامه ای را که در حال اجرای آن بود ادامه می دهد.

منابع تحریک وقفه

هر وقفه برای به وقوع پیوستن نیاز به یک منبع تحریک دارد. در AVR دو نوع وقفه داریم: وقفۀ خارجی که منبع تحریک آن تغییر وضعیت سیگنال روی تعدادی از پایه های خارجی است و وقفۀ داخلی که منابع تحریک آن ها حاصل یک سری تغییرات، مقایسه ها، اجرا یا انجام شدن یک سری کارهای بلوک های داخلی است. در AVR تقریباً تمام بلوک ها دارای وقفه هستند. مثل وقفۀ سرریز تایمر، وقفۀ یوزارت یا وقفۀ اتمام انتقال در ارتباط SPI.

جدول-وقفه-ها-در-AVR

تصویر 1 – جدول وقفه های میکروکنترلر ATmega128A

جدول-وقفه-ها-در-AVR

تصویر 2 – ادامۀ جدول وقفه های میکروکنترلر ATmega128A

جدول-وقفه-ها-در-AVR

تصویر 3 – ادامۀ جدول وقفه های میکروکنترلر ATmega128A

از این به بعد خودِ آن واقعه را که موجب وقفه می شود، وقفه می نامیم. یعنی وقفه را خودِ آن واقعه تلقی می کنیم و می گوییم وقفه اتفاق افتاده است. همچنین اگر وقفۀ خاصی باشد نام آن را می گوییم. مثلاً می گوییم: وقفۀ خارجی شماره یک اتفاق افتاده است یا وقفۀ مقایسۀ تایمر صفر اتفاق افتاده است. همچنین منابع تحریک وقفه را منابع وقفه می نامیم.

روتین وقفه یا روتین سرویس وقفه (ISR – Interrupt Service Routine)

قسمتی از برنامه را که قرار است با اتفاق افتادن وقفه، اجرا شود روتین وقفه می گویند. این قسمت از برنامه، شبیه به یک تابع است و در یک آدرس از حافظۀ Flash ذخیره می شود (که این آدرس در بردار وقفه ذخیره می شود). میکروکنترلر در حال اجرای دستورهای حلقۀ بی نهایت while است. با اتفاق افتادن وقفه دستورهای حلقۀ while را رها می کند و به روتین وقفه پرش می کند و دستورهای روتین آن را اجرا می کند و پس از اتمام دستورهای روتین وقفه دوباره به حلقۀ while برمی گردد و دستورهای بعدی را ادامه می دهد.

این روتین در کدویژن دارای سینتکس نوشتاری خاصی است. مثلاً برای نوشتن روتین وقفۀ خارجی شمارۀ 2 باید آن را به صورت زیر بنویسیم:

interrupt [EXT_INT2] void ext_int2_isr(void)
{...}

در نرم افزار اتمل استودیو نیز کافی است بنویسیم ISR و در پرانتز جلوی آن بردار وقفۀ مورد نظر را می نویسیم. برای مثال روتین وقفۀ سرریز تایمر صفر به صورت زیر است:

ISR(TIMER0_OVF_vect)
{...}

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

بردار وقفه مکانی از حافظۀ Flash است که دربرگیرندۀ “آدرس روتین وقفه” است. هر یک از روتین های وقفه (ISR) در میکروکنترلر AVR یک مکان از حافظۀ Flash را در اختیار می گیرند که به آن آدرس روتین وقفه می گوییم. آدرس روتینِ وقفه (یعنی آدرسِ ISR)، در یک مکان خاص قرار می گیرد که به این مکان خاص بردار وقفه می گویند. یعنی بردار وقفه دربرگیرندۀ یک آدرس است که در آن آدرس، روتین وقفه ذخیره شده است. خود بردار وقفه نیز در آدرس خاصی از Flash قرار دارد که در تصاویر 1 تا 3 در ستون Program Address قابل مشاهده است. شمارۀ بردار وقفه نیز بیانگر اولویت یک وقفه است. هر چه شمارۀ بردار وقفه بیشتر باشد اولویت آن وقفه کمتر است و بالعکس. در میکروکنترلر Atmega128 تعداد این بردارها 35 عدد است که بردار شمارۀ 1 آن مربوط به reset می باشد. یعنی وقفۀ reset دارای بالاترین اولویت است. 34 بردار دیگر مربوط به وقفه های خارجی و داخلی است که پس از reset وقفه های خارجی بالاترین اولویت را دارند.

مراحل وقفه در AVR

اتفاق افتادن وقفه شامل مراحل زیر است:

  • وقفه با یکی از منابع وقفه روی می دهد.
  • میکروکنترلر دستوری را که در حال اجرای آن است انجام می دهد و آدرس دستور بعدی را در پشته ذخیره می کند.
  • سپس از بردار وقفه، آدرس روتین وقفه را به دست می آورد و به آن آدرس پرش می کند.
  • و دستورهای نوشته شده در روتین مورد نظر را اجرا می کند و به انتهای آن می رسد. سپس از آن روتین خارج می شود.
  • در نهایت آدرسِ دستوری را که در پشته ذخیره کرده بود از پشته برمی دارد و در شمارندۀ برنامه (Program Counter) قرار می دهد و به اجرای ادامۀ برنامه می پردازد.

وقفه های خارجی در AVR

منظور از وقفه های خارجی (External Interrupt)، وقفه با منبع خارجی است. منابع وقفه در وقفۀ خارجی تغییر وضعیت سیگنال روی تعدادی از پایه های میکروکنترلر است. این تغییرات می تواند لبۀ بالا رونده یا پایین روندۀ سیگنال و یا سطحِ منطقی Low باشد. در تنظیمات وقفۀ خارجی می توان تعیین کرد که وقفه به کدام یک از وضعیت ها حساس باشد. به طور مثال اگر تعیین کنیم به لبۀ بالا رونده حساس باشد، هرگاه سیگنالِ ورودی به پایۀ مورد نظر یک لبۀ بالا رونده داشته باشد، وقفه اتفاق می افتد. میکروکنترلر Atmega128 تعداد 8 وقفۀ خارجی دارد (INT0 تا INT7). پایه های وقفه های خارجی ATmega128 به صورت زیر هستند.

پایۀ میکروکنترلر وقفۀ خارجی
PD0 INT0
PD1 INT1
PD2 INT2
PD3 INT3
PE4 INT4
PE5 INT5
PE6 INT6
PE7 INT7

جدول 1 – پایه های وقفۀ خارجی

رجیسترهای وقفۀ خارجی

برای فعال کردن وقفۀ خارجی باید بیت I از رجیستر SREG وهمچنین بیت های مربوط به وقفۀ خارجی مورد نظر در رجیستر EIMSK فعال شود. در ادامه رجیسترهای مربوط به بلوک وقفۀ خارجی را می بینیم.

بیت I در SREG

رجیستر وضعیت (SREG یا Status Register) در میکروکنترلرهای AVR شامل 8 پرچم (flag) است که نتایج برخی از عملیات ریاضی در آنها قرار می گیرد. پرچم I در این رجیستر، پرچم مجوز کلی وقفه هاست. اگر در پرچم I یک بنویسیم، مجوز کلی وقفه ها صادر می شود. این بیت مانند یک سوییچ کلی است. اگر فعال باشد (I=1) آنگاه هر وقفه ای که فعال شود و منبع وقفۀ آن عمل کند، وقفه اتفاق می افتد و روتین آن اجرا می شود. اما اگر پرچم I غیر فعال باشد (I=0)، وقفه هایی که فعال می شوند و منبع آنها عمل می کنند، هیچ یک از آنها اتفاق نمی افتد و در نتیجه روتین آنها  اجرا نمی شود. پس پرچم I در SREG فعال کننده و غیرفعال کنندۀ کلی وقفه هاست. (نکته: منظور از عمل کردن منبع وقفه، تحریک شدن وقفه است.)

رجیستر وضعیت در

جدول 2 – رجیستر وضعیت

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

#asm("sei")

و با استفاده از دستور اسمبلی زیر این پرچم را غیر فعال (0) کرد:

#asm("cli")

در اتمل استودیو برای استفاده از دستور اسمبلی نیازی به # نیست. در اتمل استودیو می توان از طریق یکی از دو دستور زیر پرچم کلی وقفه ها را فعال کرد:

asm("sei")
sei();

و از طریق یکی از  دو دستور زیر آن را غیر فعال کرد:

asm("cli")

cli();

در بیشتر موارد فعال کردن پرچم I قبل از حلقۀ بی نهایت while است. زیرا معمولاً تا قبل از آن، مقدار دهی به رجیستر ها است و بهتر است قبل از حلقۀ بی نهایت while، وقفه ای اتفاق نیفتد. به صورت زیر:

void main(void)
{
...
#asm("sei")

while(1)
{
   ...
}
}

همچنین می توان در ابتدای روتین وقفه ها نیز پرچم I را غیر فعال کرد تا هنگام اجرای روتین وقفه، وقفۀ دیگری اتفاق نیفتد. اما باید در آخر روتین وقفۀ مورد نظر دوباره پرچم I را فعال کرد. برای مثال داریم:

interrupt [EXT_INT2] void ext_int2_isr(void)
{
 #asm("cli")	
 ...
 #asm("sei")
}

رجیستر EICRA و EICRB

در میکروکنترلر ATmega128، دو رجیستر به نام های EICRA و EICRB وجود دارد که با مقدار دهی به آنها تعیین می کنیم که وقفۀ خارجی به کدام تغییر وضعیت سیگنال (لبۀ بالا رونده، لبۀ پایین رونده، هر دو لبۀ بالا رونده و پایین رونده یا سطح Low) حساس باشد. هر دو بیت از این دو رجیستر، مربوط به یک وقفۀ خارجی است. نام هر بیت نیز ISCnx است که ISC مخفف Interrupt Sense Control، n شمارۀ وقفۀ خارجی (بین 0 تا 7) است. x نیز که مقدار 0 و 1 را می گیرد نمایانگر 4 حالت است که در ادامه گفته خواهد شد.

جدول 3 – رجیستر EICRA

جدول 4 – رجیستر EICRB

جدول زیر بیانگر نوع حساسیت وقفۀ خارجی شمارۀ 0 تا 3هستند. (n بین 0 تا 3)

توضیح ISCn0 ISCn1
وقفۀ خارجی شماره n حساس به سطح منطقی Low (صفر ولت) است 0 0
این حالت رزرو شده است 1 0
وقفۀ خارجی شماره n حساس به لبۀ پایین رونده است 0 1
وقفۀ خارجی شماره n حساس به لبۀ بالا رونده است 1 1

جدول 5 – نوع حساسیت وقفۀ خارجی صفر تا 3

جدول زیر بیانگر نوع حساسیت وقفۀ خارجی شمارۀ 4 تا 7هستند. (n بین 4 تا 7)

توضیح ISCn0 ISCn1
وقفۀ خارجی شماره n حساس به سطح منطقی Low (صفر ولت) است 0 0
وقفۀ خارجی شماره n حساس به هر دو لبۀ پایین رونده و بالا رونده است 1 0
وقفۀ خارجی شماره n حساس به لبۀ پایین رونده است 0 1
وقفۀ خارجی شماره n حساس به لبۀ بالا رونده است 1 1

جدول 6 – نوع حساسیت وقفۀ خارجی 4 تا 7

مثال: اگر ICS20=0 و ICS21=1 باشد، وقفۀ خارجی شمارۀ 2 حساس به لبۀ پایین رونده است.

مثال: اگر ICS50=1 و ICS51=1 باشد، وقفۀ خارجی شمارۀ 5 حساس به لبۀ بالا رونده است.

مثال: اگر ICS70=0 و ICS71=0 باشد، وقفۀ خارجی شمارۀ 7 حساس به سطح منطقی Low است.

مثال: اگر ICS40=1 و ICS41=0 باشد، وقفۀ خارجی شمارۀ 4 حساس به هر دو لبۀ بالا رونده و پایین رونده است.

رجیستر EIMSK

با این رجیستر تعیین می کنیم که کدام وقفۀ خارجی فعال باشد. با 1 شدن هر بیت از این رجیستر وقفۀ خارجی متناظر آن بیت، فعال می شود. و با صفر شدن هر بیت وقفۀ خارجی متناظر آن، غیر فعال می شود.

جدول 7 – رجیستر EIMSK

رجیستر EIFR (پرچم وقفه های خارجی)

این رجیستر، وضعیت عمل کردن منابع وقفۀ خارجی را نشان می دهد و شامل 8 پرچم می باشد. هر گاه یکی از منابع وقفۀ خارجی عمل کند، پرچم متناظر آن در رجیستر EIFR یک می شود و اگر پرچم کلی وقفه ها (بیت I در SREG) فعال باشد، وقفه اتفاق می افتد و روتین آن اجرا می شود. هنگامی که یک وقفۀ خارجی اتفاق می افتد پرچم متناظر آن در رجیستر EIFR یک می شود و یک باقی می ماند و در انتهای روتین وقفه به طور خودکار (در AVR) صفر می شود. این پرچم ها هم خواندنی و هم نوشتنی هستند و فقط در صورتی که منبع وقفه عمل کند 1 می شوند و اینگونه نیست که با نوشتن 1 در آنها وقفه ای اتفاق بیفتد. بیت های پرچم اینگونه اند که اگر در برنامه، درون آنها 1 بنویسیم، پاک می شوند یعنی بیت صفر می شود و اگر در آن صفر بنویسیم، پرچم تغییری نمی کند. بنابراین می توان به طور خلاصه گفت این پرچم ها با عمل کردن منابع وقفه 1 می شوند و با یک نوشتن در آن ها صفر (پاک) می شوند. گاهی برنامه نویس لازم دارد در جایی از برنامه یا جایی از روتین وقفه پرچم آن را پاک کند، در این صورت می تواند درون پرچم مورد نظر 1 بنویسد تا پرچم پاک شود. در غیر این صورت با اتمام روتین وقفه، پرچم خودش پاک می شود.

نکته مهم: در AVR پرچم های وقفه در انتهای روتین وقفه به صورت خودکار پاک می شوند.

جدول 8 – رجیستر پرچم های وقفۀ خارجی

ویدئوی 1 – راه اندازی وقفه خارجی در AVR

تمرین وقفۀ خارجی

همۀ پایه های پورت A را میکروکنترلر Atmega128 خروجی کنید. به هر کدام از پایه های وقفۀ خارجی شمارۀ 0، 1، 4 و 6 یک مقاومت پول آپ وصل کنید و با کلید آنها را به زمین وصل کنید. پایۀ وقفۀ خارجی شمارۀ 2 را با یک مقاومت پول دون (pull down) کنید و با کلید به VCC وصل کنید. به پایۀ وقفۀ خارجی شمارۀ 5 یک سوییچ دو وضعیتی وصل کنید که در یک وضعیت، پول آپ و در وضعیت دیگر پول دون شود. سپس برنامه ای بنویسید که وقفه های خارجی شمارۀ 0 و 6 را حساس به سطح منطقی صفر، وقفه های خارجی شمارۀ 1 و 2 را حساس به لبۀ بالا رونده، وقفۀ خارجی شمارۀ 4 را حساس به لبۀ پایین رونده، وقفۀ خارجی شمارۀ 5 را حساس به هر دو لبۀ بالا رونده و پایین رونده کند. همچنین:

1- با فشرده شدن کلید وقفۀ خارجی شمارۀ 0، پایه های پورت A را به مدت 500 میلی ثانیه 1 و سپس 0 کند.

2- با رها شدن کلید وقفۀ خارجی شمارۀ 1، پایه های پورت A را 10 بار با تأخیر 200 میلی ثانیه 1 و 0 کند.

3- با فشرده شدن کلید وقفۀ خارجی شمارۀ 2، پایه های پورت A را 1 کند.

4- با فشرده شدن کلید وقفۀ خارجی شمارۀ 4، پایه های پورت A را 0 کند.

5- با هر تغییر وضعیت سوییچ روی پایۀ وقفۀ خارجی شمارۀ 5، سطح منطقی پایه های پورت A را تغییر دهد.

6- با رها شدن کلید وقفۀ خارجی شمارۀ 6، پایه های پورت A را 5 بار با تأخیر 400 میلی ثانیه 0 و 1 کند.

(کلاک میکروکنترلر 8 مگاهرتز داخلی باشد)

نکته: قبل از حلقۀ بی نهایت while، در رجیستر SREG پرچمِ I را یک کنید.

برنامۀ نوشته شده و فایل شبیه سازی آن در پیوست موجود است.

از بررسی وقفه در AVR و بلوک وقفۀ خارجی نتیجه می گیریم:

  1. با توجه به این که در استفاده از وقفه ها، CPU درگیر چک کردن اتفاقات نمی شود، سرعت و کارایی میکروکنترلر در اجرای برنامه بیشتر می شود.
  2. در AVR دو نوع منبع تحریک برای وقفه ها داریم. یکی منابع تحریک خارجی که به آن وقفۀ خارجی می گوییم و دیگری وقفه های داخلی هستند.
  3. در AVR برای وقفه ها اولویت وجود دارد. اولویت RESET از همۀ وقفه ها بیشتر است. پس از آن وقفۀ خارجی صفر تا 7 دارای اولویت بیشتری است.
  4. سینتکس نوشتاری روتین وقفه در نرم افزارهای مختلف ممکن است متفاوت باشد.
  5. هر روتین وقفه در واقع شبیه یک تابع است که در جایی از حافظۀ flash ذخیره می شود. آدرس روتین وقفه در بردار وقفه قرار می گیرد. بردار وقفه نیز خود بخشی از حافظۀ flash است که دربرگیرندۀ آدرس روتین وقفه است.
  6. وقفه در AVR شامل مراحل اتفاق افتادن وقفه، انجام دستور در حال اجرا و ذخیرۀ آدرس دستور بعدی در پشته، برداشتن آدرس روتین وقفه از بردار وقفه و پرش به آدرس روتین وقفه، اجرای روتین وقفه، قرار دادن آدرس دستوری که در پشته ذخیره شده بود در شمارندۀ برنامه و ادامۀ اجرای دستورها می باشد.
  7. وقفه های خارجی شمارۀ صفر تا 3 می توانند با سطح Low، لبۀ پایین رونده و یا لبۀ بالا روندۀ یک سیگنال اتفاق بیفتند.
  8. وقفه های خارجی شمارۀ 4 تا 7 می توانند با سطح Low، لبۀ پایین رونده یا لبۀ بالا رونده و یا هر دو لبۀ یک سیگنال اتفاق بیفتند.
  9. برای اتفاق افتادن هر وقفه ای در AVR باید پرچم کلی وقفه ها (بیت I در SREG) فعال (1) شود.
  10. برای صفر کردن پرچم های وقفه در رجیستر EIFR باید در آنها 1 نوشت.

رضا اسدی

رضا اسدی

مدیر یوبرد، خالق و توسعه دهندۀ پلتفرم یوبرد، مجری پروژه های الکترونیکی، فعال در صنعت آسانسور، سابقه فعالیت در صنعت خودرو و همکاری در صنعت پزشکی و صنایع دیگر، آموزگار آموزش های یوبرد

آموزش میکروکنترلرهای ARM سری STM32 یوبرد

آموزش میکروکنترلرهای AVR یوبرد

آموزش میکروکنترلرهایARM سری LPC یوبرد

آموزش Arduino یوبرد

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

راه-اندازی-dac-stm32

راه اندازی DAC در STM32

راه اندازی DAC در STM32، ویژگی های DAC در میکروکنترلرهای STM32F1، بلوک دیاگرام DAC در STM32، اتصالات راه اندازی DAC در میکروکنترلر STM32F107VC، نمونه کد رجیستری راه اندازی واحد DAC در میکروکنترلرهای STM32F1، ساخت موج سینوسی با STM32، راه اندازی مبدل دیجیتال به آنالوگ STM32 با توابع HAL

راه-اندازی-سون-سگمنت-با-آردوینو

راه اندازی سون سگمنت با آردوینو

راه اندازی سون سگمنت با آردوینو UNO، راه اندازی سون سگمنت 4 تایی آند مشترک با آردوینو، اتصال سون سگمنت به آردوینو، کتابخانۀ سون سگمنت برای آردوینو، نمونه کد راه اندازی سون سگمنت، نمایش اعداد در سون سگمنت 4 تایی، نکات راه اندازی سون سگمنت

راه-اندازی-adc-در-آردوینو

راه اندازی ADC در آردوینو

راه اندازی ADC در آردوینو، راه اندازی LCD گرافیکی KS0108 با کتابخانۀ U8g2، اتصالات لازم برای راه اندازی ADC و LCD گرافیکی KS0108، نمونه کد راه اندازی ADC آردوینو، فرمول محاسبۀ دما با TMP36، راه اندازی سنسور دما با آردوینو، راه اندازی فتوسل (LDR) با آردوینو

18 دیدگاه ها

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

    پاسخ
    • سلام. خواهش میکنم. در میکروکنترلرها مداراتی برای تشخیص لبۀ پالس (بالا رونده یا پایین رونده) وجود داره. هر وقت لبه ای اتفاق بیفته یعی سیگنال از سطح منطقی Low (یا High) به سطح منطقی High (یا Low) تغییر وضعیت بده، این مدار لبۀ پالس رو آشکار میکنه. با این تفسیر هر وقت سیگنال تغییر وضعیت بده و لبه ای به وجود بیاد، وقفه اتفاق میفته. برای حساسیت به سطح منطقی Low نیازی به آشکارسازی لبۀ سیگنال ورودی نیست. هر وقت سیگنال ورودی از سطح منطقی High به سطح منطقی Low تغییر وضعیت بده و مدتی توی سطح منطقی Low بمونه، وقفه اتفاق میفته. در واقع دلیل به وجود اومدن وقفه، پایین بودن سطح منطقی سیگنال هستش. برای این که وقفه اتفاق بیفته باید سیگنال ورودی، تا یه مدتی Low بمونه. مثلاً اگه دستوری در حال اجرا باشه و سیگنال روی پایۀ وقفۀ خارجی میکروکنترلر در زمان کوتاهی Low بشه و قبل از اتمام دستور در حال اجرا دوباره High بشه، وقفۀ خارجی اتفاق نمیفته. برای اتفاق افتادن وقفۀ خارجی توی این حالت باید سیگنال تا زمانی که دستور در حال اجرا تموم میشه، در سطح منطقی Low باقی بمونه.
      این که چرا توی میکروکنترلرهای AVR تحریک وقفه خارجی با سطح منطقی Low وجود داره و با سطح منطقی High وجود نداره به معماری و سخت افزار میکروکنترلرهای AVR برمی گرده. میشه این طوری هم تعبیر کرد که توی میکروکنترلرهای AVR چون روی پایه های وقفه خارجی مقاومت Pull Down داخلی نداریم، بنابراین تحریک وقفه با سطح منطقی High هم نداریم. و چون مقاومت Pull Up داخلی روی پایه های وقفه خارجی وجود داره، تحریک وقفه با سطح منطقی Low برای این میکروکنترلرها تعریف شده.

      پاسخ
  2. سلام. مطلب خوبی بود ممنون. فقط یه ایراد داره. توی دیتاشیت atmega128 نگفته وقفه های خارجی به هر دو لبه حساس باشن. ولی اینجا شما توی جدول 6 حالت دوم رو نوشتید حساس به هر دو لبه.

    پاسخ
    • سلام. بله. توی دیتاشیت جدید ATmega128A برای وقفه های صفر تا 3 و 4 تا 7 به اشتباه جداولی شبیه هم آورده که توی اون وقفه های 4 تا 7 بدون حساسیت به هر دو لبه هستن. در واقع وقفه های 4 تا 7 به هر دو لبه هم حساسن و جدول 6 درسته. این موضوع هم توی دیتاشیت قدیمی تر ATmega128 وجود داره، هم توی کدویژن وقتی کدویزارد رو باز میکنیم.

      پاسخ
  3. سلام مهندس. یه سوال دارم. توی همه کدها می بینم که بیت i از رجیستر وضعیت رو با دستور اسمبلی #asm ("sei") یک می کنن. خواستنم بپرسم ببینم میشه به صورت دستی مثلاً با نوشتن این دستور اونو یک کرد؟
    SREG|=(1

    پاسخ
    • سلام. بله میشه. به این روش هم میشه مقدار دهی کرد.

      پاسخ
  4. سلام وقت شما بخیر . من در یک برنامه ساده در روتین وقفه خارجی مقدار یک پین از میکروی attiny13 رو برابر یک قرار دادم ، در حلقه اصلی برنامه چیزی ننوشتم . برنامه درست کار میکنه منتهی با یک بار اجرای وقفه پین خروجی یک میشه و بعد از پایان روتین وقفه ، خروجی دوباره به حالت اول بر میگرده ، یعنی صفر میشه .

    پاسخ
    • سلام. وقتتون بخیر. احتمال داره به خاطر یه اتفاق میکرو ریست بشه و دستورهای پیکربندی اون پایۀ خروجی که اول تابع main مقدار دهی شدن دوباره اجرا بشه. دلیل دیگه ای به ذهنم نمی رسه. پایه ریست رو پول آپ کنید و تست کنید

      پاسخ
  5. سلام وقت بخیر
    اگر اجرای برنامه ای که برای avr نوشتیم در پروئوس به صورت real time نباشه ممکنه در عمل هم به صورت real time اجرا نشه؟

    پاسخ
    • سلام. خیلی ممنون. اگه ایراد از برنامه ای که نوشتید نباشه، و مشکل از پروتئوس باشه، برنامه real time اجرا میشه. به مقدار فیوزبیت های مربوط به انتخاب منبع کلاک دقت کنید.

      پاسخ
  6. سلام و عرض ادب
    یک سوال داشتم اینکه ممکنه وقفه ها در حین اجرا با هم تداخل پیدا کنند ؟ مثلا وقتی وقفه سر ریز تایمر 3 اتفاق میافته و داره دستور وقفه رو اجرا میکنه در همین حین مثلا وقفه خارجی INT0 اتفاق بیافته و cpu برنامه وقفه قبلی رو رها بکنه و برنامه وقفه جدید رو اجرا کنه

    پاسخ
    • سلام. بله. امکانش هست. البته به طور معمول توی AVR وقتی وقفه اتفاق میفته، و برنامه به روتین وقفه پرش میکنه، پرچم کلی وقفه ها صفر میشه. بنابراین وقفۀ دیگه ای نمیتونه اتفاق بیفته. دست کم برای وقفه های خارجی که من قبلا تست کردم به این صورت بوده. برای این که وقفۀ دیگه اتفاق بیفته، باید ابتدای روتین وقفۀ در حال اجرا، پرچم کلی وقفه ها دوباره یک بشه. البته این کار ممکنه روال برنامه رو با مشکل روبه رو کنه.

      پاسخ
  7. سلام مهندس اسدی.

    مدتی پیش ایده ای منباب سهولت و تسریع در انجام کارهای روزمره برایم دغدغه ای وجود آورد و با تفکر درباره کارایی آن دستگاه،موانعی برایم روشن گردید و چالش هایی بوجود آورد که با تحقیقات و مشورت
    از جامعه الکترونیک همچنین اساتید خبره این رشته و جستو جو در
    گوگل، با سایت Uboard.ir آشنا شدم و از مطالب مفید شما استاد بزرگوار استفاده کردم و تصمیم به ساخت مرحله به مرحله از پروژه
    رو گرفتم

    پر حرفی هایم را بگذارید برای مبتدی بودنم ☺️

    یک صفحه کلید ماتریسی ۴*۴ در نظر گرفته ام برای وارد کردن اطلاعات همچنین وجود LCD (ترجیها nokia) برای نمایش اطلاعات ضروریست و در آخر پردازش و ارسال بیسیم ان به دو گیرنده.

    برای اتصال این قطعات کدام میکرو کنترلر مناسب پروژه حقیر است؟
    Atmea 128، Atmega 640 یا Atmega 2560

    سپاس از محتوای آموزشی
    مسئله interrupt ورودی/خروجی وقفه ها همچنین نحوه شناسایی به زبان برنامه نویسی آن، بسیار در پروژه من کارایی دارد.

    خداقوت جناب اسدی

    پاسخ
    • سلام. امیدوارم که مطالبمون بتونه راهنمای خوبی براتون باشه.  خیلی لطف دارید. توی انتخاب یه میکروکنترلر از ATmega640 و ATmega2560 و ATmega128 دو تا موضوع مطرحه.

      یکی حافظه شون که به ترتیب 64 و 256 و 128 کیلوبایت حافظۀ Flash دارن. 

      میکروکنترلرهای ATmega640 و ATmega2560 هر کدوم 8 کیلوبایت حافظۀ SRAM دارن.

      میکروکنترلر ATmega128 هم 4 کیلوبایت حافظۀ SRAM داره.

      بسته به برنامه ای که می نویسید باید میکروکنترلر مورد مناسب رو انتخاب کنید.

      موضوع دیگه تعداد پایه های ورودی/خروجیه. باید ببینید که از چند تا پایۀ IO میکروکنترلر استفاده می کنید. مثلاً برای صفحه کلید 8 پایه لازمه. و مثلاً برای LCD 4 تا پایه از میکروکنترلر رزرو میشه. اگه ماژول ها و المان های دیگه ای هم دارید که میخواید با میکروکنترلر راه اندازی بشن ببینید که چند تا پایه اشغال میشه. میکروکنترلرهای ATmega2560 و ATmega640 نسبت به ATmega128 تعداد پایه های IO بیشتری دارن. خواهش میکنم. لطف دارید. موفق باشید

      پاسخ
  8. سلام مثالی را میتوان گذاشت و شما با وقفه انجام دهید

    پاسخ
    • سلام. توی این نمونه کد که برای میکروکنترلر ATmega128 نوشته شده، با فشردن دکمه های متصل شده به پایه های ورودی وقفۀ خارجی شمارۀ صفر و یک (پایه های PD0 و PD1)، وضعیت پایه های PA0 و PA1 تغییر می کنه. دکمه ها به پایۀ ورودی وقفۀ خارجی وصل شده و سر دیگه شون به زمین وصل میشه. این نمونه کد هم توی نرم افزار کدویژنه

      #include 
      #include 
      
      interrupt [EXT_INT0] void ext_int0_isr(void)
      {
      	delay_ms(300);
      	while((PIND & (1<<0)) != (1<<0));
      	PORTA ^= (1<<0);
      }
      
      interrupt [EXT_INT1] void ext_int1_isr(void)
      {
      	delay_ms(300);
      	while((PIND & (1<<1)) != (1<<1));
      	PORTA ^= (1<<1);
      }
      
      void main(void)
      {
      DDRA |=(1<<DDA1) | (1<<DDA0);
      PORTD |=(1<<PORTD1) | (1<<PORTD0);
      
      EIMSK |= (1<<INT1) | (1<<INT0);
      EIFR |= (1<<INTF1) | (1<<INTF0);
      
      #asm("sei")
      
      while (1)
            {
            // Place your code here
      
            }
      }

       

      پاسخ
  9. با سلام
    در پالس های ایجاد کننده وقفه چطور میتوانیم بانس ایجاد شده توسط پوش باتون را حذف کنیم؟

    پاسخ
  10. سلام سوال بنده اگه یه وقفه در کدویژن تعریف کنیم و در تابع مین حلقه وایل بینهایت ننویسیم وقفه عمل میکند ولی همین برنامه در اتمل استدیو نوشته بشه عمل نمیکنه علت چی میتونه باشه

    پاسخ

یک دیدگاه بنویسید

نشانی ایمیل شما منتشر نخواهد شد.

ضبط پیام صوتی

زمان هر پیام صوتی 4 دقیقه است