سلام دوستان. سیسوگ در قسمت قبلی آموزش میکروکنترلر STM32 به معرفی وقفه خارجی در میکروکنترلر STM32 پرداخت. حالا که فرا گرفتیم چطور وقفه خارجی را در میکروکنترلر STM32 تعریف کنیم، در این قسمت قصد داریم بررسی کنیم چطور چند وقفه خارجی در یک برنامه داشته باشیم و چطور باید آنها از یکدیگر تفکیک کنیم. پس با سیسوگ همراه باشید.
به محیط CubeMX میرویم و تغییرات را مطابق عکس زیر اعمال میکنیم. سه خروجی مجزا و سه اینتراپت خارجی را برای میکروکنترلر STM32 تعریف میکنیم:
همانطور که مشخص شده ما سه اینتراپت خارجی و سه خروجی مجزا انتخاب کردیم. قرار است برنامه بدین صورت باشد که با فعال شدن هر کدام از اینتراپتهای خارجی، وضعیت خروجی متناظر با آن بالعکس شود. بدین منظور با کلیک راست کردن روی هر کدام از پایههای اینتراپت خارجی لیبل مناسب آن را متناسب با هر خروجی تعیین میکنیم.
در ادامه به صفحه configuration میرویم و دکمه GPIO را میزنیم، هر سه پایه اینتراپت را روی لبه بالا رونده قرار میدهیم و آنها را پول دان داخلی میکنیم:
حالا تنظیمات را OK میکنیم و سپس دکمه NVIC را میزنیم و تنظیمات را مطابق عکس زیر اعمال میکنیم:
خوب همانطور که در شکل میبینید، سه اینتراپت خارجی داشتیم ولیکن در اینجا دو گزینه برای فعال سازی اینتراپت خارجی وجود دارد. دلیلش هم این است که اینتراپت خارجی 2 و 3 چون شماره پینهایشان در محدوده 10 تا 15 است زیر مجموعه گزینه EXTI line[15:10] هستند و اینتراپت خارجی 1 بدلیل اینکه شماره پینش در محدوده 5 تا 9 است زیر مجموعه گزینه EXTI line[9:5] میباشد. در ادامه توضیحات در مورد محدودههای مشخص شده برای اینتراپتهای خارجی بیشتر توضیح داده خواهد شد. فقط نکته بسیار مهمی که باید ذکر شود این است که شما نمیتوانید همزمان دو وقفه خارجی برای دو پین متناظر از دو پورت متفاوت را داشته باشید. به عنوان مثال اگر شما در حالی PB15 را قبلاً به عنوان اینتراپت خارجی انتخاب کردهاید اگر در همان حال اینبار PA15 را هم به عنوان اینتراپت خارجی تنظیم کنید، مطابق شکل زیر خود به خود اینتراپت خارجی PB15 منتفی میشود و تنظیم پایه PB15 به حالت پیشفرض بر میگردد.
بعد از طی مراحل تنظیمات را ok میکنیم و از CubeMX خروجی میگیریم و پروژه را با نرم افزار keil باز میکنیم. قبل از اینکه به متن برنامه برویم بهتر است ابتدا به قسمت معرفی بردارهای وقفه برویم تا بیشتر با محدوده توابع وقفههای خارجی آشنا شویم.
همانطور که در عکس بالا میبینید ما در برگه stm32f103xb.h و در قسمت معرفی وقفهها برای پنج بیت اول پورت، پنج روتین وقفه جداگانه داریم و برای بیت پنج تا نهم یک وقفه مشترک و برای بیت دهم تا پانزدهم یک وقفه مشترک دیگر خواهیم داشت. حال که این نکته را آموختیم بهتر است سراغ متن برنامه برویم. ابتدا به برگه stm32f1xx_it.c نگاهی میاندازیم:
خوب همانطور که مشاهده میکنید، ما در اینجا دو روتین وقفه داریم که اولی وقفه خارجی PA5 را پوشش میدهد و دومی وقفههای خارجی PB12 و PB15 را در بر میگیرد. حال باید مثل برنامه قبل تابع HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) را داخل main برنامه قرار بدهیم و کدهای مربوطه را طبق عکس زیر جایگذاری کنیم:
خوب همانطور که در برنامه مشخص است هنگام رخ دادن وقفه خارجی، ابتدا بررسی میشود که وقفه رخ داده مربوط به کدام پین مشخص است. بعد از آن متناظر با وقفه رخ داده وضعیت یک خروجی بالعکس میشود. خوب تقریباً به پاین مبحث وقفه خارجی رسیدیم ولیکن ذکر چند نکته خارج از لطف نیست.
- یک اینکه ما چگونه میتوانیم در طول برنامه یک وقفه خارجی را فعال یا غیر فعال کنیم.
- دوم اینکه چطور اولویت یک وقفه را تغییر دهیم.
- سوم اینکه چگونه میتوانیم نوع لبه تحریک یک وقفه را در تغییر دهیم.
در مورد سوال اول و دوم پاسخ بسیار ساده است. بدین منظور بهتر است به تابع MX_GPIO_Init(void) برویم تا شکل کار را متوجه شویم. حال به عکس زیر که از قسمتی از کدهای این تابع تهیه شده توجه کنید:
همانطور که در شکل مشخص است ما میتوانیم ازطریق تابع HAL_NVIC_EnableIRQ وقفه مورد نظرمان را فعال کنیم و برای غیرفعال کردن وقفه مورد نظر هم میتوانیم از تابع HAL_NVIC_DisableIRQ که در برگه stm32f1xx_hal_cortex.c قرار دارد استفاده کنیم. شکل استفاده از این دو تابع هم مشابه یکدیگر میباشد، یعنی اینکه اسم تابع را مینویسیم و آرگومان آن را هم نام وقفه خود قرار میدهیم.
و برای تعیین اولویت وقفه هم از تابع HAL_NVIC_SetPriority که مطابق عکس زیر دو آرگومان دارد استفاده میکنیم. این تابع دو آرگومان دارد که آنها بسته به اولویت وقفه میتوانند مقدار 0 تا 15 را به خود اختصاص دهند. با این توضیح که هر چه عدد کمتر باشد اولویت وقفه بالاتر است، توجه داشته باشید در این برنامه بدلیل استفاده از NVIC_PRIORITYGROUP_4 که در برگه stm32f1xx_hal_msp.c در تابع HAL_MspInit مطابق عکس دوم مشخص شده ما باید آرگومان SubPriority را مساوی صفر قرار دهیم و از طریق آرگومان PreemptPriority اولویت وقفه را مشخص کنیم.
توجه داشته باشید که در مورد بقیه وقفههای دیگر میکروکنترولر هم همین قضیه صادق است و ما میتوانیم از طریق همین فرمانها آنها را فعال و غیر فعال کنیم و یا اولویت آنها را تغییر دهیم.
حال برای اینکه متوجه شوید چگونه میتوان لبه تحریک یک وقفه خارجی را تغییر داد، باید پیکره بندی آن پین را دوباره انجام دهید. برای فهم بیشتر مسئله به عکس زیر توجه کنید:
حالا ممکن است این سوال پیش بیاید که مثلاً کلمه GPIO_MODE_IT_FALLING را از کجا آوردیم؟ راه حل آن ساده است بهتر است به محل تعریف آن برویم، در توضیح این موضوع یکبار دیگر هم این موضوع را تأکید میکنیم که برای اینکه به محل تعریف شدن یک ماکرو یا تابع برویم باید آن را در حالت انتخاب شده قرار دهیم و سپس مانند عکس زیر روی آن کلیک راست کنیم و بعد از آن گزینه Go To Definition را بزنیم تا به محل تعریف شدن آن تابع یا ماکرو برویم.
در آن محل شما میتوانید مطابق عکسهای زیر، دیگر گزینههای مناسب برای جایگذاری را ببنید:
در قسمت ششم آموزش میکروکنترلر STM32 قصد داریم با استفاده از رجیسترها لبه وقفه خارجی را تغییر دهیم. پس با سیسوگ همراه باشید.
سلام
اگر برای تریگر کردن وقفه هم لبه بالارونده رو انتخاب کنیم و هم لبه پایین رونده، در زمان وقوع وقفه چطور تشخیص بدیم که کدوم اتفاق افتاده؟
سلام
به سادگی با خودندن وضعیت جاری پین مورد وقفه 🙂
سلام
آقا مهدی دستت درد نکنه. واقعا بعضی مطالبی که تو همین آموزش به سادگی بیان کردی واقعا ناب بود و تو خیلی از این فیلم آموزشی ها و … نبود. وسط خوندن آموزشت اینقدر هیجان زده شدم گفتم اول بیام نظر بنویسم و بعد برگردم ادامشو بخونم. کانالت هم الان چک کردم دیدم عضو بودم ولی زیاد سر نمیزدم چون خیلی کانال دارم. ولی چک کردم جذاب بود و رفت تو لیست favorite ها .
سپاس از لطف شما ??
سلام این SubPriority دقیقا به چه کاری میاد؟ هرچی گشتم متوجه نشدم
توی میکروکنترلر های ARM مخصوصا خانواده های کورتکس وقفه ها میتونن تا 255 مرحله ماسک پذیر باشن ؛ یعنی 255 الوییت متفاوت داشته باشند ؛
برای مدیریت ساده تر میان و به شکل گروه و زیر گروه مدیریتش میکنن ؛ به عنوان نمونه 16 تا گروه که هر کدوم 16 تا زیر گروه دارن
SubPriority هم از همینجا میاد ، یعنی زیر گروه
سلام ای کاش بصورت ریجستری و یا لاقل بااستفاده از cmsis اموزش میدادید .. با این توانایی سیسوگ واقعا خیلی محتوای جذاب و پرباری میشد ..
همینم عالیه بی نظیرید
سلام . ممنون از پیشنهاد و لطفتون دوستون عزیز
سلام
دستتون درد نکنه
خیلی عالی بود
متشکریم
خواهش میکنم دوست عزیز
خوشحالیم که این مطالب مورد توجه قرار گرفته است.