برد STM سخت افزار

راه اندازی تایمر میکروکنترلرهای STM32

نوشته شده توسط علی زاهدی

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

 


 تاخیر delay یا تایمر STM32


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

آموزش delay در STM32 - دیجی اسپارک

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

آموزش تایمر timer در بردهای STM32 - دیجی اسپارک

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

 


پیکربندی تایمر در نرم‌افزار STM32CubeMX


پس از ساخت پروژه داخل نرم افزار STM32CubeMX مطابق بخش اول آموزش میکروکنترلرهای STM32 بایستی از نوار سمت راست یکی از تایمر های موجود در این بخش را انتخاب کنید. سپس در قسمت Mode گزینه ی Clock Source را بر روی Internal Clock تنظیم کنید. در این آموزش ما تایمر شماره یک را انتخاب کرده‌ایم.

تنظیمات بخش تایمر در نرم افزار STM32CubeMX - دیجی اسپارک

سپس در قسمت Parameter Settings با تنظیم گزینه های Prescale (PSC)  و Counter Period (ARR) میتوانید زمان مورد نظر خود را مشخص کنید. فرمول بدست آوردن زمان تایمر بصورت زیر است:

Stm32 timer formula

همانطور که در تصویر بالا مشاهده می‌کنید. فرکانس و پارامتر  Repetition Counter (RCR) بخش تایمر نیز در این رابطه تاثیر گذار است. پارامتر RCR را نیاز نیست تغییر دهید و بگذارید بر روی مقدار ۰ باقی بماند. اما برای تنظیم فرکانس بخش تایمر، بایستی از نوار بالای نرم‌افزار STM32CubeMX گزینه Clock Configuration را انتخاب کنید. در این آموزش ما فرکانس بخش تایمر را همانند فرکانس میکروکنترلر ۷۲ مگاهرتز در نظر گرفته ایم. در این آموزش قصد داریم تا زمان تاخیر ۱ ثانیه ایجاد کنیم. پس با توجه به فرمول بالا مقدار Prescale را برابر ۷۱۹۹ و مقدار Counter Period را برابر ۹۹۹۹ قرار میدهیم. اگر این اعداد را داخل فرمول قرار دهید. به عدد ۱ خواهید رسید. این ۱ مدت زمان تاخیر ایجاد شده توسط تایمر بر حسب ثانیه است. البته این فرمول فرکانس را محاسبه می‌کند. با توجه به این که ۱ هرتز و ۱ ثانیه برابر است. این فرمول درست عمل می‌کند. اما در صورتی که قصد محاسبه زمان دیگری را دارید بایستی در فرمول بالا جای صورت و مخرج را عوض کنید. تا نتجیه در واحد زمان بدست آید.

بخش دوم تایمر STM32 در نرم افزار STM32CubeMX - دیجی اسپارک

 

پس از تنظیم موارد گفته شده باید وارد بخش NVIC شده و تیک مربوط به گزینه TIM1 update interrupt را بزنید. با این عمل وقفه تایمر ۱ را فعال می‌کنید. که در ادامه با کاربرد این بخش آشنا خواهید شد.

بخش سوم راه اندازی تایمر STM32 در نرم افزار STM32CubeMX - دیجی اسپارک

برای تست برنامه پایه PC13 که متصل به LED موجود بر روی برد Bluepill است را بعنوان خروجی تعریف کرده و برای آن لیبل LED را در نظر میگیریم. سپس بایستی مطابق آموزش های قبل بخش Project Manager  را تنظیم نمایید و بر روی گزینه GENERATE CODE کلیک کنید و وارد نرم افزار KEIL شوید.

 


کدنویسی در نرم افزار KEIL


داخل نرم افزار KEIL قبل از شروع به کدنویسی پروژه بایستی روتین وقفه تایمر را به فایل main.c منتقل کنید. برای این کار ابتدا بایستی وارد فایل stm32f1xx_it.c شده و تابع مربوط به وقفه تایمر ۱ را در این فایل بصورت void TIM1_UP_IRQHandler(void) تعریف شده است را بیابید و تابع CallBack مربوط به تایمر را همانند کد زیر به این تابع اضافه کنید.

void TIM1_UP_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_IRQn 0 */
	HAL_TIM_PeriodElapsedCallback(&htim1);
  /* USER CODE END TIM1_UP_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_UP_IRQn 1 */

  /* USER CODE END TIM1_UP_IRQn 1 */
}

سپس بایستی تابعی همانند تایع زیر داخل فایل main.c قبل از تابع اصلی بنویسید. سپس میتوانید عملیات مورد نظر خود را در تابع زیر بنویسید. در این آموزش قصد داریم تا با استفاده از تایمر LED موجود بر روی برد Bluepill را هر یک ثانیه روشن و خاموش کنیم. برای این کار کافیست دستور HAL_GPIO_TogglePin را داخل تابع Callback تایمر اضافه کنیم. برای درک بیشتر این موضوع به مثال زیر توجه کنید.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
// Place your code here 
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}

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

HAL_TIM_Base_Start_IT(&htim1);
HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_1);

 در آخر  بایستی برنامه را کامپایل کرده و بر روی برد Bluepill پروگرام کنید. در صورتی که با نحوه پروگرام کردن میکروکنترلر های Stm32 آشنا نیستید. لطفا بخش اول آموزش های میکروکنترلر Stm32 را مطالعه نمایید.

 


جمع بندی تایمر STM32


همانطور که گفته شد برای ایجاد تاخیر زمانی راه های مختلفی از جمله استفاده از Delay و Timer وجود دارد. استفاده از Delay بسیار آسان است. اما باعث متوقف شدن برنامه برای مدت زمان مشخصی می شود. استفاده از Delay در برنامه های ساده و کوچک اشکالی ندارد. اما در برنامه های پیچیده و بزرگ استفاده از Delay تقریبا غیر ممکن است. برای ایجاد تاخیر زمانی راه بهتر و دقیق تری موجود است. که این راه استفاده از تایمر است. در هر یک ازمیکروکنترلر های STM32 تعدادی تایمر در اختیار شما قرار می‌گیرد. در این آموزش نحوه راه اندازی و محاسبه زمان تایمر را برای شما توضیح دادیم و با استفاده از تایمر تاخیر زمانی ۱ ثاینه ای ایجاد کردیم. و در آخر با استفاده تاخیر ایجاد شده LED موجود بر روی برد Bluepill را بصورت چشمک زن درآوردیم. در آموزش‌های بعد مدهای کاری دیگر تایمر میکروکنترلر STM32 از جمله PWM را توضیح خواهیم داد.

 


لوازم مورد نیاز


 

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

 


پروژه و دریافت بن ارسال رایگان


برای دریافت بن خرید از دانشجو کیت، کاربران بایستی با استفاده از وسایل این آموزش، پروژه را اجرا کرده و یا حتی مدار جدیدی تعریف کنید. سپس از اجرای کار فیلم گرفته و در شبکه‌های اجتماعی از جمله آپارات و اینستگرام، با هشتگ‌های #دیجی_اسپارک ،  #دانشجوکیت ،  digispark#  و  daneshjookit# منتشر کنند. سپس از طریق بخش نظرات در ادامه همین آموزش، جهت دریافت بن خرید ارسال رایگان به ارزش ۱۲۰۰۰ تومان از دانشجو کیت، لینک را زیر همین پست ارسال کنید.

 

در پایان نظرات و پیشنهادات خود را با ما درمیان بگذارید و با اشتراک گذاری این آموزش در شبکه های اجتماعی از وبسایت دیجی اسپارک حمایت کنید.

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

علی زاهدی

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

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

تبادل نظر و رفع عیب با ثبت دیدگاه

۱۶ دیدگاه

    • با سلام
      به دلیل قفل شکسته بودن این نرم افزار بنده نمیتوانم لینک برای شما قرار دهم. اما شما با سرچ جمله ” دانلود نرم افزار KEIL” در گوگل میتوانید این نرم افزار را دانلود کنید.

  • سلام
    ممنون از سایت خوبتون
    من با استفاده از توضیحاتتون پیش رفتم و از تابع callback استفاده کردم ولی فقط یکبار فرا خوانی می شد و LED فقط یکبار روشن می شد و دیگه تغییری نمی کرد، برای همین مستقیما تو فایل stm32f1xx_it.c در تابع void TIM1_UP_TIM10_IRQHandler(void) کد رو نوشتم اما تو این فایل نمی تونم LCD رو initial کنم و به کلی LCD رو نمیشناسه…
    ممنون میشم اگه بتونین راهنمایی کنین مشکل چیه یا تو این قسمت چطور میشه LCD رو فعال کرد.

    • با سلام از توجه شما سپاسگزارم
      در صورتی که تمامی مراحل را به طور صحیح طی کنید. با چنین مشکلی مواجه نخواهید شد. لطفا بار دیگر مراحل را با دقت انجام دهید. اما در صورتی که قصد انتقال توابع کتابخانه LCD و متغیر های مربوطه به فایل stm32f1xx_it.c را دارید. برای استفاده از توابع کتابخانه LCD بایستی فایل هدر کتابخانه را در فایل stm32f1xx_it.c فراخوانی کنید. و برای انتقال متغیر ها بایستی متغیر مورد نظر را در این فایل با اضافه کردن عبارت extern در ابتدای ان در این فایل دوباره تعریف کنید.

      • درود بر شما
        سپاسگزارم. مسکل من حل شد ، من تابع callback را اشتباها داخل main می گذاشتم
        ،حالا یه سوال دارم چطور میتونم مقدار زمان را اندازه بگیرم. در واقع می‌خوام تایمر روشن بشه و مقدار زمان را اندازه بگیرم و در متغیر ذخیره کنم.

  • سلام ببخشید من می‌خواستم بدونم که چجوری میتونم تایمر رو خودم با پوش باتن فعال کنم یعنی اگر پنج ثانیه پوش باتن رو نگه دارم یکی از خروجی ها تاگل بشه و ال ای دی تغییر وضعیت بده
    نمی‌خوام خودش interrupt کنه

    • با سلام
      کاربر گرامی بهتر است این مورد را در برنامه نویسی مدار دنبال کنید. در بخش نظرات امکان پیگیری چنین درخواستی فراهم نیست. اگر هم نسبت به برنامه نویسی میکرو دانش کافی ندارید، پیشنهاد میشود حتما در دوره شرکت کنید.

  • سلام ممنون از مطالب
    اگر داخل تابع نهایی
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    // Place your code here اینجا هر کدی بزاریم اجرا میشه؟نمیشه یه تابع براش نوشت؟
    HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    }

    • با سلام
      بله کدی که در این قسمت نوشته می‌شود پس از هربار سرریز شدن تایمر یک بار اجرا می‌شود. اما ایجاد تاخیر در این قسمت از کد (یعنی بخش روتین وقفه ISR) کار درستی در برنامه نویسی میکروکنترلر ها نیست. بهتر است که در این قسمت یک Flag تعریف شده و عملیات مورد نظر را داخل تابع Main پس از تشخیص Flag انجام دهید.

  • با سلام و وقت بخیر
    استاد عزیز ممنون از توضیحاتتون . سوالی در این زمینه برام پیش اومده ؛ من یه برنامه ساده نوشتم و در اون یک تایمر مثلا ۵ ثانیه ای را با اینتراپتش قبل از While فعال کردم و داخل تابع callback یک LED را Toggle کردم. جالب اینجاست به محض ران شدن برنامه یکبار تابع اینتراپت اجرا میشه!!! مگر نباید بعد از استارت تایمر مدت زمان تایمر به اتمام برسه و سرریز اتفاق بیفته و بعد از ایجاد اینتراپت ؛ تابع درون callback اجرا بشه ؟؟؟ اما اینجا به محض رسیدن میکرو به خط استارت تایمر تابع callback اجرا میشه و led را روشن میکنه. آیا این درست هستش ؟ اگر بخواهیم بعد از استارت تایمر ؛ زمان تایمر تمام بشه و تابع اجرا بشه باید چکار کنم ؟

    ممنون از شما

    • با سلام
      این مورد بستگی به تنظیمات تایمری دارد که مورد استفاده قرار داده اید. در صورتی که نیاز بایتستی مقادیر تایمر را قبل از تابع Start مجددا یک بار صفر کنید.

  • سلام
    متاسفانه آموزش شما برای کسی که تازه شروع کرده مناسب نیست و برای کسانی خوبه که بلدن و اون ها هم نمیان آموزش ببینن!