در قسمت قبلی راهاندازی LCD Nokia به کمک واحد SPI (نمایش انیمیشن روی LCD Nokia) را به صورت کامل یاد گرفتیم و در بخشهای قبلی با تایمرها آشنا شدیم و برخی کاربردهای آنها را دیدیم. یکی دیگر از کاربردهای تایمر، حالت PWM (Pluse width Modulation) یا همان مدولاسیون پهنای پالس است. در این بخش با نحوه استفاده از این حالت آشنا خواهیم شد.
همانطور که در شکل بالا مشخص است، به وسیله PWM میتوانیم از طریق کنترل Duty Cycle یا زمان on بودن و off بودن موج مربعی، ولتاژ متوسطی که اعمال میکنیم را کنترل کنیم. این عمل کاربردهای بسیار زیادی دارد که از جمله آنها میتوان به کنترل شدت روشنایی، کنترل سرعت موتور و .. اشاره کرد.
در ادامه این آموزش با چگونگی کنترل شدت روشنایی یک LED آشنا میشویم.
ایجاد پروژه
مراحل ساخت پروژه را مانند قبل طی میکنیم، کلاک و دیباگ را تنظیم میکنیم. سپس تایمر1 را به صورت زیر در حالت PWM تنظیم میکنیم:
بعد از تنظیم تایمر، بقیه بخشها را نیز مانند گذشته تنظیم میکنیم و وارد محیط Keil میشویم.
نوشتن کد
برای استفاده از PWM قبل از هر چیز ، باید شمارنده و خروجی تایمر1 را فعال کنیم، همچنین متغیرهای مورد نیاز را تعریف کنیم؛
1 2 3 4 5 | LL_TIM_EnableCounter(TIM1); //Enable Timer1's counter LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1); //Enable channel1 of Timer1(PWM) LL_TIM_EnableAllOutputs(TIM1); //Enable Timer1's outputs uint32_t Max = LL_TIM_GetAutoReload(TIM1) + 1; //Get the value of Timer1's ARR uint8_t count = 10; //Number of steps |
درون متغیر Max مقدار رجیستر ARR به اضافه یک را قرار دادهایم. اکنون به وسیله این مقدار، میتوانیم تعیین کنیم که به چه Duty Cycle ای نیاز داریم. به وسیله کد زیر، شدت نور LED به آرامی زیاد میشود تا به بیشترین مقدار خود برسد و این عمل تکرار میشود. همانطور که توضیح داده شد این عمل از طریق مدولاسیون پهنای پالس و کنترل میانگین ولتاژ اعمال شده به LED انجام میشود؛
1 2 3 4 5 | for (int i = 0; i < count; i++) { LL_TIM_OC_SetCompareCH1(TIM1, i * (Max / count)); //Set Duty cycle LL_mDelay(120); } |
در بخش بعدی در مورد نحوه ایجاد شکل موجهای مختلف توسط تایمر در حالت PWM صحبت خواهیم کرد.
سلام
از آموزش کامل و روانتان متشکرم.
یه سوالی دارم
وقتی میخوام توی فایل اصلی و تابعِ main، مقدارِ متغیری رو توی تابع LL_TIM_OC_SetCompareCH1
بریزم کامپایلر ارور میده.
میشه لطفا توضیح بدید که متغیری که میخوام مقدارشو به این تابع بدم، باید از چه نوعی باشه و کجا تعریفس کنم؟
متشکرم
سلام دوست عزیز
اگر متن خطا رو بگید خیلی بهتر میشه به دلیل اون پی برد 🙂
این آموزش خیلی کاربردی و مفید هست. مرسی.
فقط مدتی هست که آموزش جدید نذاشتید، امیدوارم ادامه دار باشه این سری LL
اگر پروتکل های ارتباطی دیگه مثل CAN و… هم بگید خیلی خوب میشه.
واقعیت سیسوگ از همه جا بهتر مفاهیم رو توضیح میده، مشخصه که وقت زیادی صرف گردآوری مطالب و … میکنید.
مرسی از تیم خوبتون.
خواهش میکنم دوست عزیز
شما لطف دارید
ولی ما که داریم این آموزش را ادامه میدیم خیلی وفته و امیدواریم تمومش هم بکنیم :-))