با نام و یاد خدا قسمت چهارم آموزش stm8 با توابع SPL با موضوع راه اندازی تایمر را میخواهیم اموزش دهیم.
در این بخش از اموزش ها میخواهیم با استفاده از یک مثال عملی و کاربردی نحوه استفاده از تایمر را اموزش دهیم.در این قسمت قرار است یک تابع تاخیر میکرو ثانیه ای با استفاده از تایمر در STM8 را برنامه نویسی کرده و انرا شرح دهیم.
میکرو مورد استفاده در این پروژه STM8S003 میباشد.
کد زیر را در فایل main.c خود کپی کنید.
#include "stm8s.h" #include "main.h" void TIM1_Config(void); _Bool inter=0; void delay_us(uint16_t reload){ TIM1_SetAutoreload(reload); TIM1_Cmd(ENABLE); while(inter==0); inter=0; TIM1_Cmd(DISABLE); } void main(void) { CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);//cpu divider = 1 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);// hsi divider = 1 TIM1_Config(); GPIO_Init(GPIOA,GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_FAST); enableInterrupts(); while (1){ GPIO_WriteReverse(GPIOA,GPIO_PIN_3); delay_us(1000); } } void TIM1_Config(void){ CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1 , ENABLE); TIM1_DeInit(); TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_DOWN, 16, 0); TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE); TIM1_Cmd(DISABLE); } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */
متغیر inter را به صورت extern در ابتدای فایل stm8s_it.c تعریف میکنیم.
extern _Bool inter;
سپس در تابع INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11) که در فایل stm8s_it.c تعریف شده است کد زیر را کپی کنید.
inter=1; TIM1_ClearITPendingBit(TIM1_IT_UPDATE); return;
اکنون شما با دانلود کد خود روی میکرو و اتصال پایه PORTA.3 به اسیلسکوپ مشاهده خواهید کرد که هر یک میلی ثانیه این پایه تغییر وضعیت خواهد داد.
بریم سراغ توضیح کدها
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);//cpu divider = 1 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);// hsi divider = 1
قبل از توضیح این دو خط ابتدا به شمای توزیع کلاک میکرو STM8S003Px میندازیم.
همانطور که در این تصویر مشاهده میکنید این میکرو دارای دو تقسیم کننده کلاک میباشد که با متن قرمز داخل تصویر مشخص شده است.
در خط اول تقسیم کننده کلاک CPU را روی 1 قرار دادیم و بعد از ان نیز همین عمل را روی تقسیم کننده کلاک HSI انجام داده ایم. سپس تابع ()TIM1_Config را اجرا میکنیم که شامل کدهای راه کانفیگ تایمر میباشد.
void TIM1_Config(void){ CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1 , ENABLE); TIM1_DeInit(); TIM1_TimeBaseInit(16, TIM1_COUNTERMODE_DOWN, 16, 0); TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE); TIM1_Cmd(DISABLE); }
در خط اول کلاک تایمر 1 را فعال میکنیم سپس با دستور TIM1_DeInit انرا به حالت اولیه باز میگردانیم و با دستور TIM1_TimeBaseInit کانفیگ های اولیه را انجام میدهیم که ارگومان اول آن پیش تقسیم کننده کلاک برای تایمر است که انرا روی 16 قرار داده ایم. فرکانس تایمر با توجه به شمای کلاک 16 مگا هرتز بود و با تقسیم ان بر 16 کلاک تایمر میشود 1 مگاهرتز
در ارگومان دوم نوع شمارنده را مشخص کرده ایم و در ارگومان سوم گام های شمارش را برای رفتن به حالت وقفه روی 16 تنظیم کرده ایم و نهایت TIM1_RepetitionCounter را روی 0 قرار داده ایم.
با توجه به تنظیم بالا در صورت فعال کردن تایمر هر 16 میکرو ثانیه تایمر سرریز میشود که از این قابلیت سرریزی میتوانیم برای ایجاد وقفه استفاده کنیم که با دستور زیر انرا فعال میکنیم.
TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);
و در نهایت تایمر را در حالت غیر فعال نگه میداریم.
دوستان توجه داشته باشید که برای ساختن تاخیر های میکرو ثانیه ای متنوع باید گام های شمارش که تابع TIM1_TimeBaseInit روی 61 قرار دادیم را تنظیم کنیم و با توجه به کلاک میکرو ما حداقل زمانی که میتوانیم بسازیم بین 14 تا 16 میباشد یعنی کمتر از این مقدار اگر بخواهیم تاخیر ایجاد کنیم برنامه عملا کار نخواهد کرد.
حالا با استفاده از تابع زیر میتوانیم مقادیر تاخیر های متفاوتی را ایجاد نماییم
void delay_us(uint16_t reload){ TIM1_SetAutoreload(reload); TIM1_Cmd(ENABLE); while(inter==0); inter=0; TIM1_Cmd(DISABLE); }
در این تابع ابتدا مقدار تاخیر مورد نیاز را با دستور TIM1_SetAutoreload در رجیستر مربوطه قرار میدهیم (دوستان توجه داشته باشند که این دستور مقدار گام شمارش را که در بالا با تابع TIM1_TimeBaseInit تنظیم کردیم را تغییر میدهد که در واقع برای تاخیر های متفاوت ما فقط نیاز داریم که این مقدار را متغیر قرار دهیم)
سپس تایمر را فعال میکنید و پس از ان تا زمانی که وقفه رخ ندهد از حلقه while نمیتواند خارج شود پس از رخ دادن وقفه داخل زیر روال وقفه متغیر inter=1 شده و از حلقه خارج میشود سپس متغیر inter را برابر 0 قرار داده و تایمر را غیر فعال میکند.
این آموزش هم به پایان رسید امیدواریم برای عزیزان مفید واقع شده باشد. در پناه حق موفق و سلامت باشید.
3 دیدگاه. ارسال دیدگاه جدید
بی نظیر بود
سلام وقت بخیر
من وقتی تابع enableInterrupts را فراخوانی میکنم برنامه در همان خط میماند و عملا در آن خط هنگ میکند.
شما میدانید مشکل چیست؟
درود
لطفا سوالتان را داخل گروه مطرح کنید