آخرین نوشته‌ها
خانه | میکروکنترلر | دوره آموزشی AVR | مد PWM در تایمرهای AVR (بخش دوم) – (جلسه ی ۲۰)

مد PWM در تایمرهای AVR (بخش دوم) – (جلسه ی ۲۰)

ارادتمندانه سلام می کنم بهتون و سریع می رم سر اصل مطلب،

در این جلسه قراره بخش دوم مد PWM رو بهتون ارائه کنم. اگه کمی دیر شد دیگه ببخشید. همچنین اگه نیاز به یادآوری بخش اول هست، به لینک زیر مراجعه کنید:

مد PWM در تایمرهای AVR (بخش اول) – جلسه ی ۱۶

  • توضیحات
  • کدنویسی
  • شبیه سازی

PWM-II-title

یادآوری

این بار می خواهیم یاد بگیریم که چطور تایمرها را برای استفاده در مد PWM برنامه ریزی کنیم. اگر احساس می کنید که نیاز به یادآوری دارید به جلسه ی ۱۶ مراجعه کنید. البته در ابتدا یک یادآوری مختصر از جلسه ی ۱۶ خواهیم داشت. در بخش اول مفاهیم پایه ی PWM را بیان نمودیم. به طور خلاصه:

– PWM مخفف عبارت Pulse Width Modulation و به معنای مدولاسیون پهنای پالس می باشد.

– این مد با مقایسه ی یک شکل موج از قبل تعریف شده با یک سطح ولتاژ مرجع قابل تولید می باشد. (البته می توان مدارهای آنالوگ ساده ای نیز برای این کار طراحی نمود ولی نسبت به تولید آن با میکروکنترلر از دقت پایین تری برخوردارند.)

– چرخه ی کار یک شکل موج PWM از رابطه ی زیر محاسبه می شود:

D-ctcle-formula

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

آشنایی با تایمرها در سری میکروکنترلرهای AVR

تایمر صفر در میکروکنترلر AVR

تایمر یک و تایمر دو در AVR

مد مقایسه (CTC) در تایمرهای AVR

مد PWM در تایمرهای AVR – بخش اول

تعریف مسئله

برای شروع یک مسأله تعریف می کنیم. فرض کنید که نیاز داریم یک سیگنال PWM با فرکانس ۵۰ هرتز و چرخه ی کار ۴۵ درصد تولید کنیم. با توجه به این که فرکانس ۵۰ هرتز است باید داشته باشیم:

T = T(on) + T(off) = 1/50 = 0.02 s = 20 ms

و همچنین با در نظر گرفتن این که می خواهیم چرخه ی کارمان ۴۵ درصد باشد، با حل رابطه ای که در بالا آمد داریم:

T(on)  = ۹ ms T(off) = ۱۱ ms

حال برای تولید این سیگنال می توانیم از دو روش استفاده کنیم:

۱-     استفاده از تایمر در مد CTC

۲-     استفاده از تایمر در مد PWM

استفاده از مد CTC

با توجه به این که قبلا در پست «مد CTC در تایمرهای AVR» به اندازه ی کافی توضیحاتی ارائه شده است، در این جا فقط مفاهیم مربوطه را بیان نموده و کد مورد نظر را بدون توضیحات می آوریم. در ابتدا باید تایمر مناسب را انتخاب کنیم. برای این کار می توان از هریک از سه تایمر موجود در میکروکنترلر ATmega16 استفاده نمود. سپس باید مقسم فرکانس مناسب را انتخاب نمود؛ تایمر را تنظیم و مقدار دهی کرد و دیگر کارهای معمول را انجام داد. نکته ای که باید در اینجا بدان توجه شود به روز رسانی مقدار مقایسه است. یعنی باید هربار مقدار رجیستر OCRx را تنظیم نمود.

در اینجا از تایمر یک استفاده کرده ایم. ابتدا پین OC1A را خروجی کرده و مقدار صفر را در آن می ریزیم. باید مقداری اولیه را درون OCR1A بریزیم که معادل با تاخیر ۱۱ میلی ثانیه باشد، پس از این که تطبیق رخ داد پین OC1A تغییر وضعیت می دهد و یک می شود (از قبل رفتار پین خروجی مقایسه (یا همان OC1A) را در حالت تغییر وضعیت قرار می دهیم) در همین حین زیرروال وقفه اجرا شده و مقدار OCR1A را به گونه ای تغییر می دهیم که معادل با ۹ میلی ثانیه باشد. بنابراین پین OC1A به مدت ۹ میلی ثانیه یک می ماند و باز هم تغییر وضعیت می دهد. این کار را به طور تکراری انجام می دهیم و خروجی پین OC1A یک پالس PWM با چرخه ی کار ۴۵ درصد و فرکانس ۵۰ هرتز خواهد بود.

برای مشاهده ی کد نوشته شده به تب کدنویسی در بالای صفحه مراجعه کرده و «کد شماره ی ۱» را ببینید. این کد همان کد نوشته شده برای LED چشمک زن در جلسه ی ۱۵ است که فقط کمی تغییر نموده است.

استفاده از مد PWM

حالا نوبت این است که در مورد مد PWM یاد بگیریم. مد PWM در میکروکنترلر AVR به طور سخت افزاری کنترل می شود. این یعنی این که تمام وظایف (و به معنای واقعی کلمه تمام وظایف) مربوطه توسط CPU میکروکنترلر AVR انجام می گیرد. تنها کاری که ما نیاز است انجام دهیم راه اندازی و استارت کردن تایمر و تنظیم چرخه ی کار است. اما چگونه؟

در این جا برای تشریح حالت PWM از تایمر صفر در میکروکنترلر ATmega16 استفاده می کنیم. شما می توانید هر تایمر دیگر از هرمیکروکنترلری که دوست دارید را انتخاب نمایید. اجازه دهید ابتدا رجیسترهای مربوط به مد PWM برای تایمر صفر را معرفی کنیم:

رجیستر TCCR0

در جلسه ی «آشنایی با تایمر صفر» با این رجیستر آشنا شدیم. اینجا یاد می گیریم که چگونه بیت های مناسب را برای راه اندازی تایمر صفر در مد PWM تنظیم نماییم. شکل زیر این رجیستر و بیت هایش را نشان می دهد:

tccr0

الان فقط به بیت هایی توجه می کنیم که به مد pwm مربوط می شوند:

بیت های ۳ و ۶ (بیت های WGM00 و WGM01)

کلمه ی WGM مخفف عبارت Waveform Generation Mode و به معنای مد تولید شکل موج می باشد. این بیت ها را می توان به صورت “۰۱” یا “۱۱” تنظیم کرد تا یکی از دو حالت PWM برای تایمر فعال شود. بر اساس جدول زیر می توانید با تنظیم این بیت ها مد کاری تایمر صفر را تعیین کنید:

WGM00 at pwm

بیت های ۴ و ۵ (COM00 و COM01)

عبارت COM مخفف Compare Match Output Mode و به معنای «مد خروجی تطابق در مقایسه» است. این بیت ها به منظور کنترل رفتار خروجی مقایسه (پین OC0 که پین ۴ در میکروکنترلر ATmega16 می باشد) تنظیم می شوند. به عبارت دیگر این بیت ها تعیین می کنند که هر بار که در عمل مقایسه تطبیقی صورت گرفت رفتار پین OC0 چگونه باشد.  این بیت ها را می توان در هریک از دو مد PWM سریع  و PWM تصحیح فاز تنظیم کرده و رفتار پین OC0 را مشخص کرد.

جدول زیر رفتار پین OC0 در «حالت PWM سریع» را به ازای انتخاب های مختلف بیت های COM00 و COM01 نشان می دهد:

PWM سریع

حال  نگاهی به شکل موج های مد PWM سریع (که در جلسه ی ۱۶ آوردیم) بیندازیم، در صورت نیاز به یادآوری به جلسه ی ۱۶ مراجعه کنید.

fast pwm

میبینیم که سخت افزار میکروکنترلر تمامی کارها را کنترل می نماید. حتی انجام مقایسه نیز توسط CPU صورت می پذیرد. تنها کاری که ما باید انجام دهیم این است که به CPU بگوییم که به هنگام تطابق در مقایسه چه کاری انجام دهد. اینجاست که نقش بیت های COM00 و COM01 معلوم می شود. اگر این دو بیت به صورت “۱۰” تنظیم شوند پین خروجی OC0 به هنگام تطبیق صفر می شود و پس از این که شمارنده ی تایمر به مقدار حد بالا رسید OC0 یک می شود. اگر این دو بیت به صورت “۱۱” تنظیم شوند یه هنگام تطبیق مقایسه خروجی OC0 یک می شود و پس از آن به محض این که مقدار تایمر به حد بالا رسید OC0 صفر می شود. به بیان دیگر با تنظیم این دو بیت تعیین می کنیم که مد PWM سریع به صورت معکوس یا غیر معکوس عمل کند. تصویر بالا مد غیرمعکوس را نشان می دهد.

به طور مشابه برای مد PWM تصحیح فاز جدول زیر را داریم:

COM0 at correct phase pwm

همچنین شکل موج های زیر PWM تصحیح فاز در مد غیر معکوس را نشان می دهند:

correct phase pwm

با انتخاب بیت های COM01:0 (تنظیم COM01:0 به صورت “۱۰” یا “۱۱” ) رفتار OC0 را تعیین می کنیم. همانطور که در شکل موج های بالا نیز مشخص است دو لحظه را داریم: یکی تطبیق مقایسه در حال شمارش رو به بالا و دیگری تطبیق مقایسه در شمارش رو به پایین. رفتار OC0 در این دو لحظه در جدول به خوبی توضیح داده شده است. در صورتی که برای مد PWM سریع و PWM  تصحیح فاز نیاز به یادآوری دارید به بخش اول مراجعه کنید.

توجه کنید که پین OC0 یک پین خروجی است. بنابراین تأثیر تنظیمات بیت های WGM و COM فقط در صورتی اتفاق می افتد که رجیستر DDRx به طور مناسب تنظیم شده باشد. برای اطلاعات بیشتر به «کار با پورت های ورودی و خروجی در AVR» مراجعه کنید.

بیت های ۰ تا ۲ (بیت های تنظیم ساعت) :

در مورد این بیت ها در جلسه ی تایمر صفر صحبت کردیم.

رجیستر OCR0

در مورد این رجیستر نیز قبلا در مبحث تایمر صفر صحبت نمودیم. از این رجیستر به منظور ذخیره ی مقدار مقایسه استفاده می شود. اما هنگامی که تایمر صفر در مد PWM کار می کند مقدار ذخیره شده در این رجیستر در نقش چرخه ی کار ظاهر می شود. در مساله ای که در بالا تعریف کردیم چرخه ی کار برابر با ۴۵ درصد بود، در این حالت داریم:

OCR0 = 45% of 255 = 114.75 = 115

یعنی برای داشتن چرخه ی کار برابر با ۴۵ درصد باید مقدار ۱۱۵ را در OCR0 بریزیم. حالا نوبت این است که با استفاده از اطلاعاتی که از رجیسترها یاد گرفتیم، برنامه ای بنویسیم که یک پالس PWM با چرخه ی کار ۴۵ درصد تولید کند. البته در اینجا فرکانس سیگنال پالس تولیدی به فرکانس کلاک و انتخاب مقسم فرکانس ارتباط دارد. برای تنظیم سیگنال پالس تولیدی بر روی یک فرکانس خاص باید مقدار TOP یا حد بالا (که در شکل موج های بالا مشخص شده است)  را تغییر دهیم. این کار با استفاده از رجیستر ICRx انجام می شود (که تایمرهای ۸ بیتی از آن پشتیبانی نکرده و این امکان برایشان فراهم نیست). به عنوان مثال برای تایمر یک در کانال A باید مقدار ICRA را تنظیم کنیم. در مورد این رجیستر در آموزش «کنترل سرو موتور» بحث خواهیم کرد. در اینجا فرکانس کلاک میکروکنترلر را برابر با ۴ مگاهرتز در نظر می گیریم. با استفاده از مقسم فرکانس ۱۰۲۴ می توان محاسبه کرد که پس از ۱۱۵ شمارش در حدود ۳۰ میلی ثانیه زمان می گذرد. پس سیگنال پالس تولیدی ۴۰ میلی ثانیه روشن و ۳۶ میلی ثانیه خاموش خواهد بود (برای اطلاع از چگونگی محاسبات به جلسه ی «تایمرها در AVR» مراجعه کنید).

برای مشاهده ی کد نوشته شده به تب کدنویسی در بالای صفحه مراجعه کرده و «کد شماره ی ۲» را ببینید.

مثال:

این مثال تا حدی یک مثال عملی است تا استفاده از مد PWM را بهتر لمس کنیم. فرض کنیم می خواهیم یک LED چشمک زن طراحی کنیم که ابتدا با حداکثر شدت نور روشن شود و سپس به تدریج نور آن کم شود تا خاموش گردد. سپس به تدریج روشن شده و از نور کم به حداکثر شدت نورش برسد.

برای این کار باید یک سیگنال PWM را به LED اعمال کنیم. سپس چرخه ی کار را از ۲۵۵ به تدریج به سمت صفر کاهش دهیم. و سپس چرخه ی کار را از صفر به سمت ۲۵۵ به تدریج افزایش دهیم. مطابق با چرخه ی کار سیگنال PWM، ولتاژی که به LED اعمال می شود تغییر می کند. رابطه ی زیر ارتباط ولتاژ و چرخه ی کار را بیان می کند:

Vout - pwm

برای مشاهده ی کد نوشته شده به تب کدنویسی در بالای صفحه مراجعه کرده و «کد شماره ی ۳» را ببینید.

همچنین شبیه سازی انجام شده در محیط پروتئوس نیز در تب شبیه سازی و در قالب انیمیشن آورده شده است.

تمام برنامه ها در محیط CodeVisionAVR ورژن ۳٫۱۲ نوشته شده اند.

کد شماره ی ۱

برای دیدن این کد باید عضو باشید. با مراجعه به قسمت حساب کاربری در ستون سمت چپ با نام کاربری خود وارد شوید یا ثبت نام کنید.

  کد شماره ی ۲ 

برای دیدن این کد باید عضو باشید. با مراجعه به قسمت حساب کاربری در ستون سمت چپ با نام کاربری خود وارد شوید یا ثبت نام کنید.

کد شماره ی ۳  

برای دیدن این کد باید عضو باشید. با مراجعه به قسمت حساب کاربری در ستون سمت چپ با نام کاربری خود وارد شوید یا ثبت نام کنید.

شبیه سازی در محیط نرم افزار پروتئوس انجام شده است:   LED- pwm- smltn

اسیلیسکوپ را به پین OCO متصل می کنیم. همانطور که مشاهده می شود چرخه ی کار سیگنال PWM از صفر شروع شده و به ۱۰۰ درصد می رسد و سپس دوباره به تدریج کاهش می یابد تا به صفر برسد. در صورتی که LED به این پین متصل شود در طی این پروسه، LED ابتدا از حالت خاموش به حالت حداکثر روشنایی رسیده و دوباره به تدریج نورش کم می شود تا خاموش گردد و به همین ترتیب این روند تکرار می شود.

 فایل های این جلسه شامل کدهای زبان C و فایل های hex را از لینک زیر دانلود کنید:

پسورد فایل زیپ : www.microlearn.ir

دانلود فایل های pwm – بخش دوم

خب این هم از PWM ، امیدوارم که مطالبی که گفته شد براتون مفید بوده باشه. اگه سوالی از مطالب عنوان شده دارید حتما زیر همین پست بپرسید، سعی می کنیم تمام و کمال بهشون پاسخ بدیم. ما رو از نظرات و انتقاداتتون بی بهره نذارید.

درباره‌ی مجتبی

کارشناس الکترونیک و کارشناس ارشد مخابرات سیستم | زمینه ی تحقیقاتی : پردازش تصویر و تعقیب اشیاء متحرک |‌فعال در حوزه ی الکترونیک مبتنی بر میکروکنترلر | برنامه نویس و طراح بردهای الکترونیکی مبتنی بر میکروکنترلر

۱۱ ديدگاه

  1. ببخشید در wizard تنظیمات مربوط به TIMSK کجا هست ؟ و هم چنین فراخوانی (interrupt [TIM1_COMPA] void timer1_compa_isr(void
    خودمون باید دستی تنظیم کنیم ؟

    • در قسمت ویزارد کدویژن (کدویزارد) در قسمت timers/counters با توجه به این که از کدوم تایمر و کدوم وقفه ها استفاده می کنی خود کدویژن به طور اتوماتیک مقادیر رجیستر TIMSK رو تعیین می کنه. این مقادیر رو میتونی بعد از این که save, generate and exit رو زدی از داخل برنامه پیداشون کنی.
      فراخوانی زیرروال های وقفه رو هم خود کدویژن انجام میده و نیازی به دستی وارد کردن نیست. البته اگه بخوای هم میتونی دستی وارد کنی. تفاوتی نداره.

  2. سلام
    عملکرد برنامه با توجه به شکل موج اسکوپ صحیح هست منتها وقتی ال ای دی را وصل می کنم به جای آن که تغییر شدت نور دیده بشه چشمک زدن انجام میشه. فرکانس میکرو رو هم بالا انتخاب کردم درست نشد.
    ممکنه با ال ای دی داخل سیمولاتور نشه این تغییر شدت نور رو نشون داد؟!

  3. سلام خسته نباشید
    فک می کنم تو قسمت معرفی رجیستر TCCR0 و در مد PWM سریع یه اشتباهی کردید اینکه:
    بیت های COM00 و COM01 وقتی برابر با یک و یک باشند در زمان برابر شدن مقدار تایمر با OCR خروجی SET می شود و در زمان رسیدن مقدار تایمر به TOP خروجی دوباره باید صفر شود…!!!!

  4. خواهش می کنم…
    و بعد یک سوال اینکه در مد PWM پایه ای که به راحتی قابل تغییر باشه پایه OC0 هست در صورتی که بخوایم یک پایه دیگر هم زمان مثله خوده پایه OC0 عمل کند باید چیکار کنیم؟؟ یعنی برای مثال من یه برنامه دارم که دیوتی سایکل اون نسبت به زمان تغییر می کند از ۰ تا ۱۰۰ درصد ….
    حالا می خوام به جز خوده پایه OC0 یک پایه دیگر هم تغییر کند میشه راهنماییم کند خیلی ممنون میشم…

    • سلام
      اگه شما می خواید که پین دیگه ای به جز OCx در مد PWM تغییر کنه راهش اینه که دقیقا بدونید در این مد چه اتفاقی می افته. تغییرات پین OCx برا اساس زمان تطبیق و زمان سرریز تایمر هست. خب شما می تونید از وقفه سرریز و وقفه تطبیق استفاده کنید. و به صورت نرم افزاری پین مورد نظر خودتون را در زمان رخداد این وقفه ها تغییر بدید.این الگوریتم کلی هست که باید متناسب با نوع PWM تغییرش بدید تا برنامتون کار کنه.

  5. سلام متشکرم بخاطر اموزش مفید و زیباتون…..من متوجه ارتباط بین دیوتی سایکل و شدت نور ال ای دی نشدم…مگه شدت نور ال ای دی به مقدار ولتاژ بستگی نداره ؟

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

  6. سلام.ممنون ار توضیحات خوب شما.
    مثال ال ای دی عالی بود فقط اگر بخواهیم pwm رو باید پتاسیومتر کنترل کنیم بین حداقل و حداکثر چه کاری باید انجام بدیم.ممنون میشم اگه به ایمیلم جواب بدین .ghasimsamim@gmail.com

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Time limit is exhausted. Please reload CAPTCHA.

کانال تلگرام میکرولرن
  • سلام دوست من :)
  • دوس داری AVR را ساده یاد بگیری؟
  • برنامه نویسی C را توی دانشگاه خوب یاد نگرفتی؟
  • از سایت های جذاب و تکنولوژیکی دنیا خبر داری؟
  • میونت با فیلمای با نمک و جذاب رباتیک چطوره؟
  • دنبال پروژه های جذاب برای دانشگاه یا کارای مورد علاقت میگردی؟
  • پس رو دکمه ی زیر یه تلنگر کوچولو بزن