آموزش Espآموزش ESP32آموزش اینترنت اشیاپروژه های Esp

آموزش وقفه ها Interrupts در برد ESP32

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

در مجموع ESP32 برای هر هسته اش 32 وقفه دارد. هر وقفه هم از درجه اهمیت و اولویت خاصی برخوردار است. اکثر وقفه ها ( نه همه وقفه ها) به یک مالتی پلکسر وقفه متصل هستند. چون تعداد منابع تولید وقفه از خود وقفه ها بیشترند، بعضی از وقفه ها بین چندین منبع وقفه به اشتراک گذاشته میشوند.

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

دسته بندی اصلی وقفه های ESP32 براساس نوع منابعشان است و وقفه ها از این حیث به دو دسته وقفه سخت افزاری و وقفه نرم افزاری تقسیم میشوند.

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

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

وقفه های نرم افزاری

این دسته از وقفه ها، هنگامی که یک ایونت نرم افزاری مانند سرریزشدن تایمر رخ میدهد، تریگر میشوند. وقفه های تایمر یک نمونه از وقفه های نرم افزاری هستند. در آموزش بعدی که به تایمر ESP32 اختصاص یافته، بیشتر درباره این تایمرها صحبت میکنیم.

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

1-ESP32 چند وقفه را میتواند مدیریت کند؟

ESP32 برای هرهسته اش تا 32 اسلات وقفه ارائه میدهد.

2-چگونه میتوانیم از وقفه خارجی در ESP32 استفاده کنیم؟

میتوانید پایه دلخواه را به یک وقفه وصل کرده و به کمک تابع ()attatchInterrupt، یک روتین سرویس وقفه یا ISR هم به آن متصل کنید.

3-کدام پایه های ESP32 وقفه خارجی را پشتیبانی میکنند؟

تمامی پایه ها از وقفه GPIO و 10 پایه هم وقفه لمسی را پشتیبانی میکنند.

4- ESP32 کدام یک از مدهای وقفه GPIO را دارد؟

ESP32 از پنج نوع ایونت وقفه پشتیبانی میکند. این پنج دسته LOW، HIGH، CHANGE، FALLING وRISING  هستند.

وقفه های GPIO در ESP32

در ESP32، میتوانیم تمام پایه های GPIO را به عنوان منابع وقفه سخت افزاری پیکربندی کنیم. میتوان با وصل کردن پایه های GPIO به یک ISR مناسب، وقفه هر کدام از آن ها را فعال کرد. برای وصل کردن وقفه، از تابع ماکرو ()attatchInterrupt استفاده میکنیم. نحوه استفاده از این ماکرو در ادامه توضیح داده میشود.

attachInterrupt(GPIOpin, ISR, Event);

تابع ()attatchInterrupt سه آرگومان یا ورودی می پذیرد:

اگر در مورد این مطلب سوالی دارید در قسمت نظرات بپرسید

GPIOpin: این آرگومان، شماره پایه GPIO ای که به وقفه متصل میشود را مشخص میکند.

ISR: آرگومان دوم، نام تابعی است که هر بار در هنگام تریگر شدن وقفه فراخوانی خواهد شد.

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

LOW: این ایونت هرگاه وضعیت پایه LOW شد، وقفه را تریگر میکند.

وقفه های GPIO در ESP32

HIGH: این ایونت هرگاه وضعیت پایه HIGH شد، وقفه را تریگر میکند.

وقفه های GPIO در ESP32

CHANGE: این ایونت، هر گاه وضعیت پایه تغییر کرد، برای مثال از LOW به HIGH و یا از HIGH به LOW رفت، وقفه را تریگر میکند.

وقفه های GPIO در ESP32

FALLING: این ایونت هنگامی که پایه از وضعیت HIGH به وضعیت LOW رفت، وقفه را تریگر میکند.

وقفه های GPIO در ESP32

RISING: این ایونت هنگامی که پایه از وضعیت LOW به وضعیت HIGH رفت، وقفه را تریگر میکند.

وقفه در ESP32

برای مثال، برای تریگر کردن وقفه، هنگامی که وضعیت پایه GPIO4 تغییر میکند (CHANGE) میتوانیم مطابق نمونه زیر از تابع ()attatchInterrupt استفاده کنیم.

attachInterrupt(4, ISR, CHANGE);

چگونه یک وقفه را غیرفعال کنیم؟

بعضی مواقع نیاز داریم که یک وقفه را موقتا غیرفعال کنیم. در این موارد، میتوانیم از تابع ()detachInterrupt استفاده کنیم. هنگامی که این تابع برای یک پایه خاص فراخوانی میشود، وقفه متصل به این پایه غیرفعال شده و تا زمانی که تابع ()attatchInterrupt دوباره فراخوانی نشده و یا کلا سیستم ریبوت نشود، غیرفعال باقی میماند. سینتکس استفاده از این تابع را در قسمت پایین مشاهده میکنید.

detachInterrupt(GPIOPin);

روتین سرویس وقفه یا ISR

این تابع هنگام تریگر شدن یک وقفه خاص، فراخوانی میشود. سینتکس آن را در قسمت پایین مشاهده میکنید.

void IRAM_ATTR ISR() {
    Statements;
}

نام این تابع “ISR” بوده و statements همان تسک هایی هستند که باید بعد از فراخوانی این تابع، اجرا شوند. از آنجایی که ISR اجرای برنامه اصلی را متوقف میکند، توصیه میشود که از آن برای انجام تسک هایی که تا حد امکان کوتاه هستند، استفاده شود.

پارامتر IRAM_ATTR تضمین میکند که تابع ISR به جای حافظه فلش در قسمت IRAM قرار میگیرد و همین امر باعث سریعتر اجرا شدن تابع ISR نیز میشود.

مثال روشن/خاموش کردن یک LED

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

مدار روشن خاموش کردن یک LED

در تصویر زیر، مدار واقعی  که مطابق تصویر بالا روی بردبورد بسته شده است را مشاهده میکنید.

مثال روشن/خاموش کردن یک LED

#define pushButton_pin   33
#define LED_pin   32
void IRAM_ATTR toggleLED()
{
  digitalWrite(LED_pin, !digitalRead(LED_pin));
}
void setup()
{
  pinMode(LED_pin, OUTPUT);
  pinMode(pushButton_pin, INPUT_PULLUP);
  attachInterrupt(pushButton_pin, toggleLED, RISING);
} 
void loop()
{
}

به محض اینکه دکمه فشاری را فشردیم، ولتاژ پایه GPIO33 به 0 ولت افت کرده و هنگامی که دکمه را رها میکنیم، ولتاژ آن تا 5 ولت افزایش می یابد. هنگامی که ولتاژ در حال افزایش است، وقفه تریگر شده و ISR متناسب با آن که toggleLED نام دارد، فراخوانی میشود. چون که ISR تنها در لبه بالا رونده تریگر میشود، debouncing حذف میشود.

وقفه لمسی در ESP32

ESP32 از وقفه لمسی در 10 پایه ورودی لمسی پشتیبانی میکند. نحوه استفاده از وقفه لمسی هم مشابه وقفه GPIO است. برای وصل کردن وقفه لمسی، از تابع ()touchAttatchInterrupt استفاده خواهیم کرد که سینتکس آن در پایین ارائه شده است:

touchAttachInterrupt(GPIOPin, ISR, Threshold)

در اینجا GPIOpin همان پایه ای است که تماس ورودی را پشتیبانی کرده و ISR هم همان تابع روتین سرویس وقفه است. Threshold هم مقداری از تماس حس شده است که وقفه لمسی باید در آن تریگر شود. دیگر موارد دقیقا مانند مثال توضیح داده شده درباره وقفه GPIO است.

موارد موجود در فایل : سورس کامل

5 (1 نفر)

برای دریافت مطالب جدید کانال تلگرام یا پیج اینستاگرام ما را دنبال کنید.

محمد رحیمی

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

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

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