آموزش وقفهها در میکروکنترلر STM32 تعریف و استفاده از Interrupt داخلی و خارجی
آموزش وقفهها در میکروکنترلر STM32 تعریف و استفاده از Interrupt داخلی و خارجی وقفهها (Interrupts) از ابزارهای کلیدی در طراحی سیستمهای مبتنی بر میکروکنترلر هستند. استفاده از وقفهها به میکروکنترلرها این امکان را میدهد که به صورت بلادرنگ به رویدادهای داخلی یا خارجی پاسخ دهند. در STM32، به دلیل قدرت و انعطاف بالا، مدیریت وقفهها بسیار مهم است. در این مقاله، به تشریح کامل مفاهیم وقفه، انواع آن در STM32 و نحوهی استفاده از آن برای مدیریت رویدادهای مختلف میپردازیم.
بخش 1: آشنایی با مفهوم وقفهها
وقفهها مکانیزمی هستند که به میکروکنترلر اجازه میدهند در صورت وقوع یک رویداد خاص، به جای ادامهی اجرای برنامهی جاری، بلافاصله به پردازش رویداد رخ داده شده بپردازد. این مکانیزم به دو دسته کلی تقسیم میشود:
- وقفههای خارجی: شامل رویدادهایی مانند فشار دادن دکمه یا ورود سیگنال از یک دستگاه خارجی.
- وقفههای داخلی: شامل رویدادهایی که داخل میکروکنترلر رخ میدهند، مانند تایمرها و خطاهای داخلی.
بخش 2: معماری وقفهها در STM32
میکروکنترلرهای STM32 از یک واحد مدیریت وقفه به نام NVIC (Nested Vector Interrupt Controller) استفاده میکنند. NVIC امکان تعریف و مدیریت وقفهها را فراهم میکند و قابلیت اولویتبندی وقفهها و مدیریت توالی آنها را دارد.
STM32 علاوه بر NVIC، از یک واحد وقفهی خارجی به نام EXTI نیز بهره میبرد که مختص مدیریت وقفههای خارجی است. EXTI وظیفه دریافت سیگنالها از پینهای خارجی را دارد و به میکروکنترلر امکان میدهد به رویدادهای خارجی سریعاً پاسخ دهد.
بخش 3: آمادهسازی STM32 برای استفاده از وقفهها
برای استفاده از وقفهها در STM32، نیاز به ابزارهایی همچون CubeMX و HAL Library داریم که پروسه تنظیم و کدنویسی را آسانتر میکنند.
مراحل پایه برای تنظیم وقفهها:
- راهاندازی پروژه با CubeMX: ابتدا یک پروژه جدید در نرمافزار CubeMX ایجاد کنید و مدل میکروکنترلر STM32 مورد استفاده را انتخاب کنید.
- فعالسازی وقفه: پینهای ورودی یا تایمرهایی که به وقفه نیاز دارند را در CubeMX فعال کنید.
- تنظیمات EXTI: در صورتی که از وقفههای خارجی استفاده میکنید، باید پینهای مربوطه را به EXTI متصل کنید.
- اولویتبندی وقفهها: در NVIC میتوانید اولویت وقفهها را تنظیم کنید. اولویتبندی درست به جلوگیری از تداخل وقفهها کمک میکند.
بخش 4: کدنویسی وقفهها با HAL Library
با استفاده از HAL Library میتوانید به سادگی وقفهها را تعریف و مدیریت کنید.
نمونه کد برای وقفهی خارجی:
در این مثال، پین GPIO به عنوان ورودی تعریف شده و با فشار دادن دکمهای که به این پین متصل است، وقفه فعال میشود.
#include "stm32f4xx_hal.h"
// پیکربندی GPIO
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if(GPIO_Pin == GPIO_PIN_0) {
// کدی که در صورت رخداد وقفه اجرا میشود
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // تغییر وضعیت LED
}
}
int main(void) {
HAL_Init();
__HAL_RCC_GPIOA_CLK_ENABLE();
// تنظیم پین به عنوان ورودی
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
while (1) {
// کد اصلی برنامه
}
}
در این کد:
- پین GPIO0 به عنوان ورودی و به حالت وقفه (Interrupt) در حالتی که از پایین به بالا (Rising Edge) حرکت میکند، تنظیم شده است.
- در تابع HAL_GPIO_EXTI_Callback، کدی که هنگام وقوع وقفه باید اجرا شود قرار میگیرد؛ در اینجا، وضعیت یک LED تغییر میکند.
بخش 5: مدیریت وقفههای داخلی (تایمرها)
یکی از پرکاربردترین وقفههای داخلی، وقفه تایمرهاست. تایمرها در STM32 برای انجام وظایفی مانند اندازهگیری زمان یا تولید سیگنالهای PWM استفاده میشوند.
نمونه کد برای وقفه تایمر:
در این مثال، از تایمر برای ایجاد یک وقفه در هر ثانیه استفاده شده است.
#include "stm32f4xx_hal.h"
TIM_HandleTypeDef htim2;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if(htim->Instance == TIM2) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // تغییر وضعیت LED
}
}
int main(void) {
HAL_Init();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_TIM2_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim2.Instance = TIM2;
htim2.Init.Prescaler = 16000 - 1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000 - 1;
HAL_TIM_Base_Init(&htim2);
HAL_TIM_Base_Start_IT(&htim2);
HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
while (1) {
// کد اصلی برنامه
}
}
در این مثال:
- تایمر 2 برای تولید یک وقفه با فرکانس 1 هرتز تنظیم شده است.
- در هر وقفه، وضعیت LED تغییر میکند.
بخش 6: نکات کلیدی در مدیریت وقفهها
مدیریت وقفهها به طور صحیح نیاز به رعایت نکات و اصول خاصی دارد:
- کوتاه نگهداشتن کد وقفه: کدی که در روال وقفه نوشته میشود باید تا حد امکان کوتاه و سریع باشد.
- اولویتدهی مناسب به وقفهها: اولویت وقفهها بر اساس اهمیت آنها تعیین شود تا از تداخل وقفهها جلوگیری شود.
- استفاده از فلگها: برای جلوگیری از خطا در صورت وقوع وقفههای متوالی، میتوانید از فلگها برای کنترل ورود به روال وقفه استفاده کنید.
نتیجهگیری
وقفهها ابزار قدرتمندی در سیستمهای تعبیهشده و میکروکنترلرها محسوب میشوند که به توسعهدهندگان این امکان را میدهند که به صورت بلادرنگ به رویدادهای مختلف پاسخ دهند. با استفاده از STM32 و ابزارهایی مانند CubeMX و HAL Library، میتوان وقفههای داخلی و خارجی را به سادگی پیکربندی و مدیریت کرد. رعایت اصول و نکات در برنامهریزی و اولویتدهی به وقفهها باعث بهبود کارایی و دقت سیستم میشود.
آموزش وقفهها در میکروکنترلر STM32 تعریف و استفاده از Interrupt داخلی و خارجی
مطلب پیشنهادی
آموزش پروتکل های ارتباط سریال UART ، SPI و I2C در میکروکنترلر STM32