آخرین مطالب
LINK TABLES
خانه | میکروکنترلر | دوره آموزشی AVR | منابع وقفه در AVR(جلسه ۱۱)

منابع وقفه در AVR(جلسه ۱۱)

سلام می کنم به شما کاربر محترم میکرولرن 🙂

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

تعریف وقفه

وقفه پیامی است که از طرف یک وسیله جانبی تولید می شود تا از CPU درخواست سرویس کند(به زبون ساده: به CPU بگه به منم توجه کن باهات کار دارم). CPU با در یافت یک سیگنال وقفه کارهای جاری را متوقف کرده و به وسیله مورد نظر سرویس می دهد. درست شبیه زمانی که فردی در حال انجام کارهای روزمره است و با زنگ خوردن تلفن کارها را رها کرده تا به تلفن پاسخ دهد. در این مثال فرد مورد نظر نقش CPU، کارهای روزمره نقش برنامه اصلی، تلفن نقش وسیله جانبی و صدای زنگ آن نقش سیگنال وقفه را دارند.

مزیت استفاده از وقفه

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

۱) سرکشی دوره ای یا polling:

سرکشی دوره ای به این صورت است که در خلال برنامه بیت های پرچم وسیله جانبی جهت آگاهی از وضعیت آن، توسط cpu بررسی می شود و اگر آن وسیله نیاز به سرویس دهی داشت این کار توسط cpu انجام می شود. در این روش cpu باید به طور مداوم به این وسایل سرکشی کند که این کار باعث کندی برنامه و از دست رفتن زمان برای بررسی وسایل دیگر می شود.

۲) استفاده از وقفه یا interrupt:

در روش وقفه، cpu در حال اجرای روال عادی برنامه است. اما زمانی که یک وسیله جانبی نیاز به توجه cpu دارد با ارسال سیگنال وقفه باعث می شود تا cpu روال عادی برنامه را متوقف کرده و به آن توجه کند. این روش باعث می شود تا زمان cpu برای بررسی رخ دادن یک وضعیت تلف نشود.

انواع وقفه در AVR

معمولا در میکرو کنترلرها وقفه‌ها به دوسته کلی تقسیم می شوند:

  • وقفه‌های خارجی: وقفه‌هایی هستند که منبع آنها خارج از میکرو قرار دارد و با ارسال سیگنالی به پایه های مخصوصی در میکروکنترلر، وقفه ایجاد می کنند.
  • وقفه‌های داخلی: همانطور که از اسمش پیداست این وقفه‌ها سیگنال هایی هستند که داخل میکرو ایجاد می شوند. اکثر این سیگنال ها از وسایل جانبی خود میکرو مانند تایمر/کانتر ها ، ADC و … تولید می شوند. این سیگنال ها همان درخواست سرویس از CPU می باشند.

بردار وقفه

هر وقفه‌ای در AVR خانه ای  را در ROM (حافظه فلش) به خود اختصاص می دهد. زمانی که وقفه ایجاد می شود بسته به نوع وقفه، CPU بعد از اجراکردن دستور جاری به آن خانه مراجعه می کند. این خانه محتوی آدرس برنامه‌ای است که به وقفه سرویس می دهد. به مجموعه این خانه ها که هرکدام مربوط به یک نوع وقفه هستند جدول بردار وقفه و به برنامه ای که به وقفه سرویس می دهد روال سرویس وقفه(ISR) میگویند. در جدول زیر می توانید آدرس وقفه‌های مختلف در ATmega32 را مشاهده کنید:

برای باز شدن تصویر روی جعبه زیر کلیک کنید.

جدول بردار وقفه

جدول بردار وقفه

فعال کردن پاسخ گویی به وقفه‌ها

وقفه‌ها در AVR به صورت پیش فرض غیر فعال هستند.یعنی با روشن شدن میکرو هیچ وقفه‌ای کار نمی کند و باید به وسیله برنامه نویسی، وقفه‌هایی را که میخواهیم ایجاد شوند فعال کنیم. در AVR معمولا هر وسیله‌ای به طور اختصاصی دارای بیتی به نام بیت فعال ساز وقفه می باشد. با یک شدن این بیت اجازه پاسخ گویی به وقفه‌ی مربوط به آن وسیله فعال و با صفر شدن بیت مذکور اجازه پاسخ گویی به وقفه غیر فعال می شود. مکان این بیت برای هروقفه‌ای در ثبات خاصی از ثبات های I/O می باشد. اگر نیاز به یادآوری رجیسترهای I/O دارید مقاله سازماندهی حافظه در AVR را مطالعه کنید.

اگر از مباحث مربوط به ثبات وضعیت به یاد داشته باشید یکی از بیت های این ثبات “I” یا فعال ساز وقفه‌ی عمومی (Interrupt Enable) نام دارد. به وسیله ی این بیت می توان کلیه وقفه‌ها را فعال ویا غیرفعال کرد. به این صورت که اگر این بیت را یک کنیم وقفه‌ها فعال و اگر آن را صفر کنیم وقفه‌ها غیرفعال می شوند. با صفر شدن این بیت حتی اگر بیت فعال ساز وقفه برای وسیله ای یک باشد، وقفه ایجاد نمی شود. پس برای رخ دادن یک وقفه لازم است بیت فعال ساز وقفه‌ی عمومی و بیت فعال ساز وقفه‌ی اختصاصی، همزمان یک باشند. درواقع بیت فعال ساز وقفه‌ی عمومی با بیت های فعال ساز وقفه‌های اختصاصی AND شده است. در شکل زیر می توانید ثبات یا رجیستر وضعیت را مشاهده کنید:

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

مراحل اجرای یک وقفه

  1.  هنگامی که یک وقفه اتفاق می افتد cpu دستور در حال اجرا را به پایان برده و آدرس دستور بعدی (این آدرس درون رجیستر pc یا program counter قرار دارد) را بر روی پشته ذخیره می کند.
  2. بسته به نوع وقفه، میکروکنترلر به خانه ثابتی از حافظه فلش واقع در جدول بردار وقفه پرش می کند.
  3. در این خانه، آدرس روال سرویس وقفه یا ISR وجود دارد و میکرو با پرش به این آدرس، شروع به اجرای دستورات موجود در روال سرویس وقفه می کند تا به دستور آخر روال  یعنی RETI برسد.
  4. این دستور شمارنده برنامه یا pc را با آدرس دستوری که در مرحله یک در پشته ذخیره شده بود بارگذاری می کند. این کار با برداشتن دو بایت بالای پشته و قرار دادن آن در PC انجام می شود. سپس میکرو شروع به اجرای دستورات از این آدرس می کند.

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

روال سرویس وقفه برنامه ای است که توسط برنامه نویس نوشته می شود تا عملیاتی را با ایجاد وقفه انجام دهد. اما چرا این برنامه را در آدرسی که مربوط به بردار وقفه است نمی نویسیم؟

آدرس های بردار وقفه فقط ۲ بایت فضا دارند. پس باید ISR را در محل دیگری نوشت و آدرس آن را در محل بردار وقفه قرار داد.

مواردی که در مورد پشته و دستورات push و pop و نوشتن ISR در آدرسی دیگر گفته شد مخصوص زبان اسمبلی می باشد. اما در زبان C کامپایلر این کارها را مدیریت می کند و نیازی به نگرانی برنامه نویس وجود ندارد. تنها کافی است یک تابع برای روال وقفه نوشته شود.

شاید بپرسید در صورتی که در طول پردازش روال سرویس وقفه‌ای، وقفه‌ی دیگری رخ دهد چه اتفاقی می افتد؟

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

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

اولویت وقفه

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

وقفه‌های خارجی

بعد از توضیح موارد کلی و اصول وقفه‌ها حال وقفه‌های خارجی را به صورت خاص بررسی می کنیم.

یک وقفه‌ی خارجی در اثر سیگنالی از یک وسیله جانبی خارج از میکرو که وارد پایه خاصی از میکرو می شود اتفاق می افتد. برای مثال در میکروکنترل ATMEGA32 سه پایه برای وقفه‌ی خارجی با نام های INT0 ,INT1 ,INT2 وجود دارد که در شکل زیر مشخص شده است:

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

رجیستر GICR

نام این رجیستر از Global interrupt control register گرفته شده است. با استفاده از بیت های شماره ۵، ۶ و ۷ که در تصویر زیر قابل مشاهده است می تواند قابلیت پاسخ گویی به وقفه های خارجی ۰ تا ۲ را فعال کرد. INT0 برای وقفه خارجی صفر استفاده می شود و سایر وقفه های خارجی نیز به همین ترتیب فعال می شوند. البته باید توسط رجیستر SREG بیت فعال ساز وقفه عمومی فعال شود و توسط رجیستر MCUCR حساسیت به لبه یا سطح مشخص شود که در ادامه توضیح داده می شود.

بیت های ۲ تا ۴ رزرو هستند و از آن ها استفاده ای نمی شود. بیت ۰ و ۱ نیز برای تغییر مکان بردارهای وقفه مورد استفاده قرار می گیرد که خارج از بحث جلسه امروز است.

رجیستر MCUCR

نام این رجیستر از MCU Control register گرفته شده است.

همان طور که گفتیم، وقفه های سخت افزاری یا حساس به سطح هستند یا حساس به لبهبا تنظیم بیت های رجیستر MCUCR می توان نوع حساسیت را تعیین کرد. برای INT0 از بیت های ۰ , ۱ و برای INT1 از بیت های ۲ و ۳ استفاده می شود. در تصویر زیر این رجیستر را مشاهده می کنید:

درتصویر زیر نحوه تنظیم حساسیت به سطح یا لبه برای INT0 توضیح داده شده است:

تمام موارد گفته شده درباره INT0 در مورد INT1 هم صدق می کند.برای تنظیم نوع حساسیت INT1کافیست در جدول بالا بیت های ISC10 و ISC11 را به همین شیوه برای INT1 اعمال کنید.

رجیستر MCUCSR

نام این رجیستر از MCU Control and Status Register گرفته شده است.

نحوه حساسیت وقفه‌ی خارجی دو یا INT2 در ATMEGA32 توسط بیت ISC2 در ثبات MCUCSR تنظیم می شود. وقفه‌ی خارجی دو فقط در دو حالت تنطیم می شود.

  • اگر ISC2 صفر باشد INT2 حساس به لبه پایین رونده می شود.
  • اگر ISC2 یک باشد INT2 حساس به لبه بالا رونده می شود.

رجیستر GIFR

نام این رجیستر از Global interrupt flag register گرفته شده است. این رجیستر پرچم وقوع وقفه‌های خارجی است. هر وقت یک وقفه‌ی خارجی رخ دهد، پرچم متناظر با آن یک می شود. همان طور که در شکل زیر می بینید، پرچم متناظر با وقفه‌ی خارجی صفر INTF0 است و برای وقفه‌های یک و دو نیز به همین ترتیب.

اما نکته ی مهمی که در رابطه با این پرچم ها وجود دارد صفر شدن آن ها است. اگر پاسخ گویی به وقفه را فعال کرده باشیم، با وقوع وقفه و پرش به آدرس بردار وقفه، پرچم متناظر هم صفر می شود. اما اگر به صورت نرم افزاری بخواهیم آن را صفر کنیم باید روی آن ۱ نوشته شود. این قانون برای تمامی پرچم های AVR صادق است.

مثال:

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

زبان C در کدویژن:

برای دیدن این کد باید عضو باشید. با مراجعه به قسمت حساب کاربری در ستون سمت چپ با نام کاربری خود وارد شوید یا ثبت نام کنید.

توصیه می شود برای تمرین بیشتر مباحث امروز حتما پروژه وقفه، که مربوط به یک رقص نور می باشد را تمرین کنید. برای مشاهده این مقاله اینجا کلیک کنید.

جلسه منابع وقفه هم به پایان رسید. چند باری مرور لازمه تا خوب بهش مسلط بشید. البته برای وقفه‌ها داخلی می تونید به پست های تایمرها، ارتباط سریال، پروتکل SPI، پروتکل I2C و مبدل آنالوگ به دیجیتال سری بزنید و با وقفه‌ها داخلی هم آشنا بشید. البت اصول کلی اون ها به همین شکل هست. در آخر اگه ما رو از طریق لینک شبکه های اجتماعی که همین پایین وجود داره به دوستاتون معرفی کنید خیلی کارتون بیسته. 😉

درباره ی احسان عبداللهی

احسان عبداللهی هستم | کارشناسی الکترونیک خوندم و کارشناسی ارشد مخابرات| سعی کردم هر چیزی را به صورت کاربردی دنبالش برم برای همین از کارشناسی کار با میکروکنترلرهای AVR و ARM، برنامه نویسی C و طراحی PCB را تخصصی کار کردم و از کارشناسی ارشد برنامه نویسی متلب، پایتون و Computer vision و deep learning را به صورت تخصصی و کاربردی کار کردم | الان هم سعی میکنم همیشه خودم را به روز نگه دارم و لذت کار کردن با دنیای برنامه نویسی و امبدد سیستم ها را به دیگران انتقال بدم

۳۱ دیدگاه

  1. من هرکاری میکنم رجیستر GIFR نمیفهمم.

  2. سلام
    علت استفاده نکردن از رجیستر GIFR در این برنامه چیست؟؟؟؟

  3. سلام ممنون بابت مطالب مفیدتون.

    میکرو سه نوع وقفه دارد.

    اگر ما بخواهیم برنامه ای بنویسیم که نیاز به ۵ وقفه داشته باشد چیکار باید بکنیم؟؟؟

  4. با سلام وخسته نباشید وتشکر از وقتی که میگذارید
    یه سوال
    بنده یک برنامه بسکام ای وی آر نوشتم (البته کار با این مقوله رو ظرف ۳ روز و از اینترنت یاد گرفتم) و حالا نیاز به دو چیز دارم
    ۱- اینکه با قطع برق / برنامه در همون خط متوقف بشه تا اینکه بعد از وصل برق دوباره ادامه روال را دنبال کنه
    ۲- اینکه چگونه یک EEprom را در مدار قرار بدم (کدوم پایه ها به کجا متصل بشن)
    البته میدونم سوال دوم ربطی به این مبحث نداره اما اگر امکانش هست جواب بدید

    باز هم از زحمت شما تشکر میکنم

  5. با سلام
    برنامه ای نوشتم که در آن وقفه خارجی برای انجام کار خاصی فعال شده و خود برنامه اصلی دیتای مشخصی را به صورت uart به میکروی دیگر ارسال می کند.این برنامه در محیط پروتوس به درستی کار می کند ولی در محیط سخت افزار واقعی تنها اطلاعات در صورتی درست ارسال می شوند که وقفه عمومی از کار افتاده باشد.می خواستم ببینم مشکل از کجاست و اگه امکانش هست کمکم کنید.البته این رو هم بگم که وقفه خارجی ربطی به ارسال اتطلاعات ندارد و برای منظوری دیگری استفاده شده است یعنی در ارسال یا عدم ارسال اطلا نقشی ندارد ولی خب در سخت افزار من این مشکل وقفه عمومی را دارم.از نرم افزار کد ویژن و میکرو مگا۳۲ استفاده میکنم.
    با تشکر

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

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

    • سلام
      اصولا این کار درست نیست و بهتره الگوریتم برنامه نویسی خودتون رو تغییر بدید. اگه بدونم برنامه چه کاری قرار بکنه بهتر میتونم راهنمایی کنم. ولی اگه خیلی ضروریه به جای استفاده از وقفه، منبع تولید وقفه را به پین ریست میکرو وصل کنید.

  7. توضیحاتتون خیلی روان و مفید بود
    خیلی ممنونم
    خسته نباشید

  8. واقعا عالی بود
    هم توضیحات شما و هم ویرایش جدید مقاله.
    همگی خسته نباشبن ایشالا

    • مرسی. همراهی شما با ما و نظرات دلگرم کنندتون بهترین خسته نباشید برای گروه میکرولرن هست. 🙂

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

    • خواهش میکنم محمد جان. پاسخ دادن به سوالای شما خیلی خیلی لذت بخشه. اما ابتدا یک نکته را بگم این پست کامل بررسی و ویرایش مجدد شد تا برای مخاطب ساده تر باشه فهمش. الان کد تغییر کرده و اگه شما دستورات داخل حلقه while را حذف کنید، تا زمانی که کلید فشار داده نشه هیچ وقت LED روشن نمیشه. دلیلش سخت نیست. چند خط از برنامه جاشون باهم عوض شده. اما اگه به کدی که توی کامنت بالا نوشتی دقت کنی متوجه میشی که ابتدا اجازه وقفه عمومی را فعال کردی و سپس وقفه صفر را هم فعال کردی و اون رو به سطح صفر حساس کردی و پین صفر از پورت A راهم خروجی در نظر گرفتی. میکرو بعد از روشن شدن تمام پورت هاش صفر هست. خب تا اینجا یک بار وقفه رخ میده و بدون فشرده شدن کلید LED روشن میشه. سپس در دستور بعدی مقاومت پول آپ پورت D را فعال کردی. در ادامه برنامه میره داخل حلقه بینهایت که هیچ کاری انجام نمیده. توصیه میکنم توضیحات جدید کد را کامل بخونی حتما متوجه میشی.

  10. این همان کد بالاست …فقط دستور داخل حلقه ی بی نهایت را حذف کردیم.
    در این صورت بدون فشار دادن کلید ال ای دی همیشه روشن می ماند.
    آیا می توان گفت اگر دستوری برای اجرا نباشد دستور وقفه مدام اجرا می شود؟!
    #include
    #include
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    PORTA|=0b00000001;
    delay_ms(500);
    }

    void main(void)
    {
    #asm(“sei”)// global interrupt enable
    GICR|=(1<<INT0); // active int0
    DDRA=0x01;// PINA0 is out
    PORTD|=0xff;// active pull up resistances

    while (1)
    {
    // PORTA=0;// turn LED off
    }
    }

    • درود
      در کدی که شما نوشتید اگه وقفه خارجی تحریک بشه LED روشن میمونه. اما در هیچ جای برنامه دستوری برای خاموش کردن LED وجود نداره. پس برای همیشه روشن می مونه. اما شما گفتید “اگر دستوری برای اجرا نباشه دستور وقفه مدام اجرا می شه”، این حرف دقیق نیست یعنی: دستور وقفه زمانی اجرا می شه که وقفه تحریک شده باشه و ربطی نداره که دستور دیگری وجود داره یا خیر. در این حالت تا زمانی که وقفه خارجی تحریک نشده باشه برنامه داخل حلقه while بینهایت منتظر می مونه و طبیعتا هیچ کار خاصی انجام نمیشه تا تحریک وقفه رخ بده.

  11. خیلی ممنون

  12. یعنی اگر وقفه حساس به سطح باشد : بیت فعال ساز وقفه عمومی low باشد و بیت فعال ساز وقفه اختصاصی high باشد و پرچم هم بالا رود در این حین به محض اینکه بیت فعال ساز وقفه عمومی high شود دیگر پرش به بردار وقفه صورت نمیگیرد؟

    • در وقفه های خارجی در حالت حساس به سطح وضعیت پایه مستقیم خوانده میشه و پرچم intfx تاثیری نمیبیند.

  13. ببخشید اگه امکانش هست توضیحات GIFR را با یک مثال ساده توضیح دهید
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    PORTA|=0b00000001
    #asm(“sei”)
    }
    منظورتون اینه ؟ اگه اینجوریه مگه با یک بار اجرا ISR ، بیت فعال ساز وقفه عمومی صفر میشود ؟

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

  14. منظورتون از ” هنگام استفاده از حالت حساس به پایین بیت فعال ساز وقفه عمومی در سرویس روال وقفه فعال شود” یعنی خط ۱۳ام از برنامه نویسی سی در داخل تابع وقفه int0 قرار بگیرد؟

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

  16. آقا مرسی.
    دمت گرم خیلی مطالبت خوبه و خیلی هم خوب توضیح میدی
    من که حسابی با مطالبت عشق میکنم.
    موفق باشی

  17. هر چند توضیح رجیستر GIFR یه مقداری گیج کننده بود ولی کلا مقاله عالی و تقریبا کاملی بود.
    با تشکر از وقتی که گذاشتی

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

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