آموزش ایجاد سیگنال PWM در میکروکنترلر AVR
محتویات
سلام. PWM چیست ؟ آموزش کامل استفاده از PWM برای میکروکنترلر AVR در اتمل استودیو را آماده کردیم.
نحوه استفاده از PWM در Atmel Studio
Pulse Width Modulation یا همان (PWM) یک روش قدرتمند است که با ثابت نگه داشتن فرکانس، طول پالس را تغییر می دهد. این روش امروزه در بسیاری از سیستم های کنترل استفاده می شود. کاربرد PWM محدود نیست و از آن در طیف گسترده ای از برنامه ها مانند کنترل سرعت موتور، اندازه گیری، کنترل قدرت، ارتباطات و … استفاده می شود. در تکنیک PWM می توان به راحتی سیگنال خروجی آنالوگ را به سیگنال های دیجیتال تبدیل کرد. در این آموزش به طور کامل با PWM ، اصطلاحات آن و اجرای آن روی میکروکنترلر AVR توسط کامپایلر اتمل استودیو آشنا میشویم. همچنین میتوانید از میکروکنترلر Atmega32 نیز استفاده کنید.
پین PWM در میکروکنترلر AVR ات مگا 16
Atmega16 چهار پین اختصاصی برای PWM دارد. این پین ها PB3 ، PD4 ، PD5 ، PD7 هستند. در تصویر زیر این پین ها مشخص شده اند.
همچنین Atmega16 دارای دو تایمر 8 بیتی و یک تایمر 16 بیتی است. Timer0 و Timer2 تایمر 8 بیتی هستند در حالی که Timer1 تایمر 16 بیتی است. برای تولید PWM باید تایمر ها را بشناسیم زیرا از تایمر برای تولید PWM استفاده می شود.
در این آموزش PWM از Timer2 استفاده خواهیم کرد. شما می توانید هر چرخه وظیفه (Duty Cycle) را انتخاب کنید. اگر نمی دانید چرخه وظیفه در PWM چیست، پس بگذارید کوتاه توضیح دهم.
سیگنال PWM چیست؟
مدولاسیون عرض پالس (PWM) یک سیگنال دیجیتالی است که بیشتر در مدارهای کنترل مورد استفاده قرار می گیرد. زمان بالا ماندن سیگنال “on time” است و زمان سیگنال کم ماند “off time” نامیده می شود. دو پارامتر مهم برای PWM وجود دارد که در زیر آن ها را مورد بحث میدهیم.
Duty Cycle (چرخه وظیفه) PWM
درصد زمانی که سیگنال PWM بالا باقی می ماند به عنوان چرخه وظیفه شناخته می شود.
مثلا سیگنال پالس 100ms است، اگر سیگنال برای 50ms بالا و برای 50ms پایین باشد ، می توان گفت که چرخه وظیفه 50٪ است. به طور مشابه اگر پالس به مدت 25ms بالا و 75ms در حالت پایین باشد ، چرخه وظیفه 25٪ خواهد بود. توجه کنید که ما فقط طول حالت HIGH را محاسبه می کنیم. برای درک کامل PWM می توانید از عکس و فرمول زیر استفاده کنید.
Duty Cycle (%) = On Time/(On Time + Off Time)
بنابراین ، با تغییر چرخه وظیفه می توانیم مقدار PWM را تغییر دهیم و این کار در نتیجه باعث تغییر در روشنایی LED شود. ما در کنترل روشنایی LED از چرخه وظیفه با درصد های مختلف استفاده خواهیم کرد.
بعد از انتخاب Duty Cycle ، مرحله بعدی انتخاب حالت PWM خواهد بود. حالت PWM مشخص می کند که چگونه می خواهید با PWM کار کنید. عمدتا 3 نوع حالت PWM وجود دارد.
- PWM سریع (Fast PWM)
- PWM فاز صحیح (Phase Correct PWM)
- PWM فاز و فرکانس صحیح (Phase and Frequency Correct PWM)
PWM سریع در جایی استفاده می شود که تغییر فاز مهم نیست. با استفاده از Fast PWM ، می توانیم مقادیر PWM را به سرعت باز کنیم. PWM سریع در مواردی که تغییر فاز مثلا بر عملکرد کنترل موتور اثر می گذارد قابل استفاده نیست، بنابراین در چنین برنامه هایی از حالتهای دیگر PWM استفاده می شود. از آنجا که ما روشنایی LED را کنترل خواهیم کرد که تغییر فاز تأثیر زیادی نداشته باشد ، بنابراین ما از حالت سریع PWM استفاده خواهیم کرد.
اکنون برای تولید PWM ، تایمر داخلی را کنترل خواهیم کرد تا شمارش انجام شود و بعد ازی ک تعداد خاص به صفر برگردد. این کار دوره را تعیین میکند. اکنون میتوانیم یک پالس را کنترل کنیم. یعنی وقتی پالس بالا میرود با یک تعداد مشخص روشن شود. وقتی شمارنده به 0 برمی گردد، پالس خاموش میشود.
انعطاف پذیری زیادی در این زمینه وجود دارد زیرا همیشه می توانید به کانتر / تایمر دسترسی داشته باشید و پالس های مختلف را با یک تایمر تهیه کنید.این موضوع برای وقتی که می خواهید چندین LED را به طور همزمان کنترل کنید بسیار مناسب است. اکنون بیایید LED را به میکروکنترلر Atmega16 متصل کنیم تا PWM را راه اندازی کنیم.
برای اطلاعات بیشتر، مقاله PWM چیست را مشاهده کنید.
شماتیک مدار کنترل نور LED با PWM
در تصویر زیر شماتیک کامل مدار کنترل نور ال ای دی با PWM و استفاده از میکروکنترلر Atmega 16 را مشاهد میکنید.
قطعات مورد نیاز برای آموزش PWM
- میکروکنترلر AVR Atmega16 – دیتاشیت مگا 16
- کریستال16Mhz
- خازن 100nF – دو عدد
- خازن 22pF – دو عدد
- ال ای دی – دو عدد
- دکمه
ما از OC2 برای PWM یعنی پین Pin21 – PD7 استفاده می کنیم. بنابراین یک LED را به پین PD7 Atmega16 متصل کنید.
استفاده از PWM در میکروکنترلر های AVR
کد کامل پروژه را میتوانید در انتهای صفحه مشاهده کنید. با تنظیم رجیستر Timer 2 برنامه نویسی Atmega16 را شروع کنید. بیت های رجیستر Timer2 به شرح زیر است و می توانیم بیت ها را بر این اساس تنظیم کنیم.
ما در مورد همه بیت های Timer2 بحث خواهیم کرد تا بتوانیم با استفاده از برنامه نویسی، PWM دلخواه را بدست آوریم.
در رجیستر Timer2 عمدتا چهار قسمت وجود دارد:
FOC2 (مقایسه نیرو مقایسه برای Timer2): بیت FOC2 وقتی تنظیم می شود که بیت WGM یک حالت غیر PWM را مشخص کند.
WGM2 (سازنده موج برای Timer2): این بیتها ترتیب شمارش شمارنده برای حداکثر مقدار (TOP) شمارنده را کنترل می کنند.
COM2 (مقایسه حالت خروجی برای Timer2): این بیت ها عملکرد خروجی را کنترل می کنند.
TCCR2 |= (1<<WGM20)|(1<<WGM21);
بیت WGM20 و WGM21 را به عنوان HIGH تنظیم کنید تا حالت سریع PWM فعال شود.
WGM00 | WGM01 | مود تایمر 2 |
0 | 0 | مود عادی Normal |
0 | 1 | CTC |
1 | 0 | PWM, فاز صحیح |
1 | 1 | PWM سریع |
TCCR2 |=(1<<COM21)|(1<<CS20)|(0<<CS21)|(0<<CS22);
همچنین ما از مقیاس گذاری استفاده نکرده ایم بنابراین رجیستر Clock source را 001 تعیین کرده ایم. یعنی ردیف دوم جدول زیر:
CS22 | CS21 | CS20 | توضیحات |
0 | 0 | 0 | No clock source(Timer/Counter stopped) |
0 | 0 | 1 | clkT2S/(No Prescaling) |
0 | 1 | 0 | ClkT2S/8(From Prescaler) |
0 | 1 | 1 | ClkT2S/32(From Prescaler) |
1 | 0 | 0 | ClkT2S/64(From Prescaler) |
1 | 0 | 1 | ClkT2S/128(From Prescaler) |
1 | 1 | 0 | ClkT2S/256(From Prescaler) |
1 | 1 | 1 | ClkT2S/1024(From Prescaler) |
گزینه های مقایسه حالت خروجی (COM) برای حالت سریع PWM در زیر آورده شده است:
COM21 | COM21 | توضیحات |
0 | 0 | اپراتور عادی , OC2 قطع است. |
0 | 1 | رزرو شده |
1 | 0 | تنظیم OC2 در TOP |
1 | 1 | پاک کردن OC2 درTOP |
چرخه وظیفه را از 0٪ به 100٪ افزایش دهید تا به مرور زمان میزان روشنایی افزایش یابد. مقدار آن را از 0-255 در نظر بگیرید و آن را به پین OCR2 ارسال کنید.
for(duty=0; duty<255; duty++) // 0 برای نهایت چرخه وظیفه { OCR2=duty; //افزایش نور ال ای دی به صورت آهسته _delay_ms(10); }
به همین ترتیب چرخه وظیفه را از 100٪ به 0٪ کاهش دهید تا به تدریج میزان روشنایی LED کاهش یابد.
for(duty=0; duty>255; duty--) // 0 برای نهایت چرخه وظیفه { OCR2=duty; //کاهش نور ال ای دی به صورت آهسته _delay_ms(10); }
کد کامل پروژه را در باکس زیر میتوانید مشاهده کنید :
#define F_CPU 16000000UL //فرکانس CPU #include "avr/io.h" #include <util/delay.h> void PWM_set(){ // PWM تنظیم DDRD |= (1<<PD7); //تنظیم پین PD7 برای خروجی PWM TCCR2 |= (1<<WGM20)|(1<<WGM21); //تنظیم بیت ها برای انتخاب حالت PWM سریع TCCR2 |=(1<<COM21)|(1<<CS20)|(0<<CS21)|(0<<CS22); //پاک کردن در حالت مقایسه } int main () { unsigned char duty; PWM_set(); while (1) { for(duty=0; duty<255; duty++) // 0 برای نهایت چرخه وظیفه { OCR2=duty; //افزایش نور ال ای دی به صورت آهسته _delay_ms(10); } for(duty=254; duty>0; duty--) // 0 برای نهایت چرخه وظیفه { OCR2=duty; //کاهش نور ال ای دی به صورت آهسته _delay_ms(10); } } }
سلام برای کنترل روشنایی یک led 24 ولت با استفاده از سنسور فتوسل و pwm آیا نیاز به تنظیم حالت خاصی در atmega هست ؟
عالی بود خیلی خوب توضیح دادین
سلام عزیز
خوشحالم که براتون مفید بوده
توضیح گنگ بود. یک مبتدی مث من رو خیلی خوب گیج میکنید. فقط صفحع درست کردی دونبال کنن. چیز بدرد بخوری نزاشتی.
سلام عزیز، برنامه نویسی در اتمل استودیو بسیار پیچیده تر از آردوینو، کدویژن و … است
سلام.من هم اولش خیلی گیج شدم و هنوزم فرقی نکرده.
ولی اینکه کامل همه توابع و … راه اندازی چیز هارو یاد میده خیلی خوبه.
همین یه مزیته.
چون کدویژن خودش کدویزارد داره و این باعث میشه بیشتر کد هارو خودش بنویسه و تو چیزی ازشون نفهمی و هیچی از کد کاملش یاد نگیری.
دوره ای وی آر را مشاهده کنید. تمام رجیستر ها و تنظیم بیت ها آموزش داده شده است و متوجه موضوع خواهید شد.
سلام برنامه در for دوم صحیح نسیت
for
(–dute=255;dute>0;dute)
سلام جناب، ممنون از اطلاع رسانیتون، ویرایش شد.
سلام من یک اسی atmega16 دارم می خوام شمارنده آن را صفر کنم لطفا راهنمایی کنید