تبلیغات

به نام خدا
با عرض سلام خدمت دوستان عزیز
در این جلسه نیز مبحث PWM را دنبال می‌كنیم. عزیزان برای درك مطالب این جلسه حتماً باید جلسات قبل را مطالعه كرده باشند. در این جلسه به  آی‌سی L298 نیز اشاراتی شده است كه دوستان می‌توانند جهت یاد‌اوری، بخش مربوط به L298 در جلسات گذشته را نیز مرور كنند.

ابتدا با توابعی كه برای ایجاد وقفه در اجرای دستورات برنامه توسط CodeVision برای كاربران در نظر گرفته شده آشنا می‌شویم.
همان‌طور كه در جلسه‌ی پیش دیدیم، در قسمت‌هایی از برنامه ممكن است نیاز پیدا كنیم تا برای لحظاتی روند اجرای دستورات را متوقف كنیم. CodeVision برای این كار توابعی را از پیش تنظیم كرده است. (در مورد مبحث «توابع» در زبان C در آینده مفصل توضیح خواهیم داد.)


delay




برای ایجاد تاخیر در روند اجرای دستورات، CodeVision دو تابع زیر را در اختیار ما قرار داده است.

delay_ms( );
delay_us( );





تابع ()delay_ms برای ایجاد تاخیر‌هایی در حد میلی ثانیه به كار می‌رود. در داخل پرانتز، یك عدد صحیح مثبت می‌نویسیم كه نشان دهنده‌ی اندازه‌ی تاخیر مورد نیز ما بر حسب میلی ثانیه است. به بیان ساده‌تر، مثلاً اگر داخل پرانتز عدد 100 را بنویسیم، روند اجرای برنامه به اندازه‌ی 100 میلی ثانیه در همان خط متوقف خواهد شد.
تابع ()delay_us برای ایجاد تاخیر‌هایی در حد میكروثانیه به كار می‌رود. نحوه‌ی استفاده از آن دقیقاً مانند ()delay_ms است.
به عنوان یك مثال عملی،همان برنامه‌ی ایجاد PWM 2.5 ولت را با استفاده از توابع delay بازنویسی می‌كنیم.

while(1)
{
PORTB.4=1;
delay_ms(5);   // 5 milliseconds delay
PORTB.4=0; 
delay_ms(5);    //5 milliseconds delay
}











 

تنها نكته‌ی بسیار مهم در استفاده از توابع delay اضافه كردن هِدِرفایل Header file  باعنوان delay.h به برنامه است.( در مورد هدر فایل‌ها هم در آینده توضیح خواهیم داد، اما در این جلسه هیچ توضیحی در مورد آن نمی‌دهیم تا از بحث اصلی یعنی PWM منحرف نشویم.) برای این كار، جمله

 ‌كه اولین جمله‌ی برنامه‌ی شما است را پیدا كنید. (این جمله را CodeWizard در برنامه‌ی شما نوشته است). حال كافیست این جمله را درست زیر ان تایپ كنید:

دقت كنید كه این دستور نیازی به « ; » ندارد !!

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

همانطور كه می‌دانید موتور‌های متعارفی كه برای ساخت ربات‌ها استفاده می‌شود،ممكن است ولتاژ‌های كاری مختلفی داشته باشند (مثلاً 12ولت، 24 ولت، 6 ولت و ...) و برای راه‌اندازی آن‌ها باید از درایور‌های موتور مثل L298 استفاده ‌كنیم.  سوالی كه ممكن است پیش آید این است كه وقتی ما میكروكنترلر را به درایور‌های موتور(مثل L298) وصل می‌كنیم و از تكنیك PWM برای كنترل سرعت موتور استفاده می‌كنیم، چه وضعیتی پیش می‌آید؟ مثلاً وقتی ما PWM مربوط به ولتاژ 2.5 ولت را تولید می‌كنیم، درایور ما چه عكس العملی نشان می‌دهد؟ آیا ولتاژ 2.5 ولت بر روی پایه‌های موتور قرار می‌گیرد؟

برای پاسخ دادن به این سوال باید به ساختار PWM دقت كنیم، ما وقتی PWM مربوط  به 2.5 ولت را تولید می‌كنیم، در حقیقت سطح ولتاژ خروجی را با فواصل زمانی برابر 0 و 1 می‌كنیم، پس اگر این خروجی را، به ورودی L298 وصل كنیم(مثلاً پایه‌ی 7)، L298 نیز موتور را با همین الگو ‌كنترل می‌كند و ولتاژی كه به موتور می‌دهد را 0 و 1  می‌كند. و همانطور كه می‌دانید، L298 هر ولتاژی كه بر روی پایه‌‌ی شماره‌ی 4 آن قرار گرفته باشد را بر روی موتور قرار می‌دهد(اگر ولتاژ كاری موتور 12 ولت باشد، باید این پایه به 12 ولت متصل شود) . پس جواب سوال بالا منفیست!!!  وقتی ما PWM مربوط به 2.5 ولت را تولید می‌كنیم، در حقیقت سطح ولتاژ خروجی در 50 درصد زمان 1 و بقیه‌ی زمان 0 است. پس اگر همان طور كه در بالا اشاره شد، این PWM به درایوری مثل L298 داده شود، و ولتاژ پایه‌ی 4 ِ آن 12ولت باشد، درایور، ولتاژ 6 ولت را به موتور می‌دهد. در نتیجه اهمیتی ندارد چه ولتاژی بر روی پایه‌ی 4 ِ L298 قرار گرفته باشد، وقتی كه ما PWM مربوط به 2.5 ولت را تولید می‌كنیم، درایور ولتاژی كه به موتور می‌دهد را 50 درصد می‌كند. در نتیجه بهتر است از این به بعد به جای آن كه بگوییم PWM مربوط به 2.5 ولت، بگوییم PWMااا50 درصد. یا به جای PWM ِمربوط به 1 ولت، بگوییم PWMااا20 درصد


PWM در میكروكنترلر‌های AVR




انجام تنظیمات اولیه برای استفاده از PWM برای راه اندازی موتور درمیكروكنترلر‌های AVR كمی پیچیده است، اما در اینجا هم CodeWizard به كمك ما آمده است و كار را كمی ساده‌تر كرده است. ما در جلسه‌ی آینده  بخشی از تنظیمات CodeWizard را بدون توضیح مطرح می‌نماییم، زیرا توضیح هر بخش از آن نیازمند مقدمات مفصلی است و تاثیر چندانی هم در روند كار ما ندارد، اما به دوستانی كه می‌خواهند میكروكنترلر را كاملاً حرفه‌ای دنبال كنند، پیشنهاد می‌كنم از منابعی كه قبلاً معرفی شده است، مطالب را تكمیل كنند.
به هر حال دوستان عزیز با انجام این تنظیمات اولیه‌ی مختصر در CodeWizard، می‌توانند از الگویی به مراتب ساده‌تر از آنچه تا به حال آموخته‌ایم، برای ایجاد PWM برای هدایت موتورهای ربات استفاده نمایند.

در میكروكنترلر‌های خانواده‌ی AVR، نیازی نیست در هربار استفاده از PWM ، چندین خط برنامه بنویسیم.  در ATmega16 چهارپایه‌ی مشخص از آی سی به این موضوع اختصاص داده شده است. یعنی این چهارپایه علاوه بر كاربرد‌های معمولی خود، این قابلیت را دارند كه در مواقع لزوم برای تولید PWM استفاده شوند.
حال سوال اینجاست كه این چهارپایه چه تفاوتی با بقیه‌ی پایه‌های خروجی آی‌سی دارند كه آن‌ها را از سایر پایه‌های خروجی میكروكنترلر متمایز می‌سازد؟
برای این چهارپایه نیازی به اجرای الگویی كه تا به حال برای ایجاد PWM فراگرفته‌اید نیست. در این روش، فقط  شما باید یك عدد صحیح بین 0 تا 255 انتخاب كنید، و طبق الگوی زیر آن را در برنامه‌ی خود بنویسید.


یك عدد صحیح بین 0 تا 255 = نام رجیستر مربوطه‌  ;

این عدد، بیانگر توان PWM شماست، و  شما توان PWM ِ مورد نیاز خود را با این عدد مشخص می‌كنید. كه 255 بالاترین توان و مربوط بهPWMااا100 درصداست، و  0 پایین‌ترین توان و مربوط به PWMااا0 درصد است.
به عنوان مثال اگر این عدد را  128 قرار دهید، همان PWMااا50 درصد را ایجاد كرده‌اید. یا مثلا اگر این عدد 51 باشد، PWMااا20 درصد بر روی پایه قرار داده‌اید.


رجیستر‌های مربوط به این 4 پایه




همانطور كه می‌دانید، برای پایه‌هایی كه در CodeWizard به صورت خروجی تعریف شده‌اند، رجیستری به نام «PORTx» وجود دارد كه هر مقداری در این رجیستر قرار داده ‌شود، مقدار پایه‌های خروجی متناظر با آن رجیستر را مشخص می‌كند.(رجوع به جلسه‌ی 24،تعریف رجیستر PORTx).
در این جلسه با 4 رجیستر دیگر آشنا می‌شویم، كه وقتی تنظیمات مربوط به PWM ِ موتور در CodeWizard را انجام  دهیم، هر مقداری كه در‌ آن‌ها ریخته شود، توان PWM پایه‌ی متناظر را مشخص می‌كنند.
این رجیستر‌ها OCR0، OCR1AL، OCR1BL و OCR2 نام دارند كه به ترتیب، متناظر پایه‌های PB.3، PD.5، PD.4  و PD.7‌ هستند.
پس مثلاً اگر در بخشی از برنامه‌ی خود بنویسیم :

OCR0=127; 



در حقیقت بر روی پایه‌ی PB.3 میكروكنترلر، PWMااا50-درصد به وجود آورده‌ایم.

به مثال‌های دیگری توجه كنید: (توضیح هر دستور در جلوی دستور و  بعد از // آورده شده است)

OCR1AL=51; // 20% Duty Cycle on PD.5
OCR1BL=255; //100% Duty Cycle on PD.4
OCR2=0;  //0% Duty Cycle on PD.7






در ادامه در مورد نحوه‌ی انجام تنظیمات اولیه‌ جهت تولید PWM در CodeWizard را توضیح خواهیم داد.

همانطور كه گفتیم ، در اینجا مجال نیست تا تمام مباحث مربوط به PWM و تایمرها را باز كنیم و مفصل به آن‌ها بپردازیم، به همین خاطر در این جلسه قسمتی از تنظیمات در CodeWizard را بدون توضیح آموزش می‌دهیم.
برای انجام تنظیمات به كمك CodeWizard، ابتدا باید طبق روندی كه در جلسات گذشته توضیح داده شد، یك پروژه‌ی جدید در CodeVision بسازید.
پس از انجام تنظیمات سایر لبه‌ها (مانند Ports، Chip و .... ) در CodeWizard، لبه‌ی Timers را باز كنید.
 همانطور كه می‌بینید میكروكنترلر ATmega16 دارای 3 تایمر مجزا است و ما برای تولید PWM باید از این تایمرها استفاده كنیم. تایمر‌ها كاربرد‌ها‌ی متعددی دارند، و یكی از مهم‌ترین مباحث در میكروكنترلر هستند، ما هم  در مورد تایمر‌ها در جلسات آینده مفصل توضیح خواهیم داد. اما در این جلسه فقط استفاده از تایمر‌ها را برای ایجاد PWM برای كنترل موتور‌های ربات استفاده می‌كنیم.


Timer0
 




Timer0 مربوط به رجیستر OCR0 است و باید به شكل زیر تنظیم شود.

نكته‌ای كه در مورد تنظیم هر 3 تایمر باید رعایت شود، این است كه در بخش "Clock Value" باید پایین‌ترین فركانس را انتخاب كنید. در این مورد توضیح مختصری می‌دهم، ولی اگر عزیزان این بند را متوجه نشوند اهمیت زیادی ندارد: اندازه‌ی فركانسی  كه انتخاب می‌كنید در این بخش، در حكم اندازه‌ی همان Delayهایی است كه برای تولید PWM به صورت عادی (كه در ابتدای جلسه‌ی قبل توضیح دادیم) استفاده می‌كنیم. یعنی در حقیقت طول موج را در نمودار ولتاژ بر زمان تعیین می‌كند. هر چه فركانس بالاتری را انتخاب كنید، طول موج كمتر می‌شود. در عمل دیده شده كه هر چه فركانس پایین‌تر باشد و در نتیجه طول موج بیشتر باشد، موتور‌ها بهتر هدایت می‌شوند. به همین خاطر در بالا گفته شد كه دوستان پایین‌ترین فركانس را برای "Clock Value" انتخاب كنند.


Timer1
 




تایمر1 باید به شكل زیر تنظیم شود. دقت كنید كه ممكن است در بخش Clock Value شما فركانسی كه در شكل زیر نمایش داده شده است را در گزینه‌ها نداشته باشید، ولی همانطور كه گفته شد فقط مهم این است كه شما پایین‌ترین فركانس را انتخاب كنید.


همانطور كه می‌بینید، تایمر1 دارای دو خروجی مجزا است كه رجیستر‌های مربوط به آن‌ها OCR1AL و OCR1BL هستند.


Timer2
 




تایمر2 میز به شكل زیر تنظیم می‌شود و مانند تایمر0 فقط یك خروجی دارد.


Watchdog
 




 یا سگ نگهبان نیز یكی از مباحث مربوط به تایمر‌هاست كه در جلسات آینده به آن خواهیم پرداخت.

حال كه همه‌ی تنظیمات لازم را در CodeWizard انجام داده‌اید، "Generate, Save and Exit" انتخاب كنید و وارد فضای برنامه نویسی شوید.

نكته‌ی بسیار مهم:
برای كنترل هر موتور، علاوه بر یك پایه‌ی
PWM، یك خروجی معمولی نیز لازم داریم تا بتوانیم به وسیله‌ی این دو پایه و به كمك درایور موتور، اختلاف پتانسیل مورد نظر را بر روی دو پایه‌ی موتور برقرار كنیم. این 2 پایه را به دو پایه‌ی ورودی L298 متصل می‌كنیم و دو پایه‌ی موتور را نیز، به دو پایه‌ی خروجی  L298 متصل می‌كنیم. حال می‌توانیم موتور را به وسیله‌ی میكروكنترلر با سرعت دلخواه كنترل كنیم. به عنوان مثال اگر بخواهیم موتور ما تقریباً با سرعت نصف بچرخد، و پایه‌های PD.6 و PD.7 (مربوط به رجیستر OCR2) را به L298 متصل كرده باشیم،برنامه‌ی زیر را باید بنویسیم:

OCR2=127;
PORTD.6=0;


و اگر بخواهیم موتور ما با همین سرعت و در جهت معكوس بچرخد، می‌نویسیم:

OCR2=127;
PORTD.6=1;




برای درك این موضوع دقت كنید كه در این حالت چه ولتاژی توسط L298 بر روی موتورها قرار داده می‌شود. همانطور كه می‌دانید، سرعت و جهت چرخش موتور وابسته به اختلاف ولتاژی است كه بر روی پایه‌های موتور قرار داده می‌شود.


 

تا به اینجا مباحث پایه‌ای در میكروكنترلر‌های AVR مطرح شده است و همین آموخته‌های دوستان، نیاز‌های اولیه‌ی شما عزیزان را برای ساخت ربات‌های نسبتاً حرفه‌ای برطرف می‌سازد.
از این به بعد، مطالب به با دامنه‌ی گسترده‌تری پیرامون سایر مباحث مربوط به رباتیك،ارائه خواهد شد. در هر جلسه مطلب جدیدی را مطرح كرده و در مورد آن توضیح می‌دهیم و دیگر مطالب به شكل كنونی به صورت زنجیره‌وار و وابسته به هم، نخواهند بود.
 طبیعتاً برای درك هر مطلبی نیاز به مقدمات و پیش‌نیازهایی است، كه در ابتدای هر جلسه  پیش نیاز‌های مطالبی كه در ان جلسه قرار است مطرح شوند، ذكر خواهد شد، تا به این ترتیب پراكندگی مطالب، دوستان را دچار سر در گمی نكند.

مجدداً از دوستان عزیزی كه مخاطب این بخش هستند و مطالب را با ما دنبال می‌كنند، تقاضا می‌شود هر پیشنهاد و انتقادی برای ارتقا سطح كیفی این بخش دارند، با ما در میان بگذارند.

تا جلسه‌ی آینده خدا نگه‌دار.