راه‌اندازی موتور DC توسط میکروکنترلر Atmega16

الکترونیک و رباتیک -> انواع موتور و درایور صنعتی 2636 2 کاربر آکادمی پارتینه

موتورهای DC جزو پرکاربردترین موتورها هستند. از این موتورها می توان تقریباً در همه جا از پروژه‌های کوچک گرفته تا تجهیزات روباتیکی پیشرفته استفاده کرد. آشنایی با راه‌اندازی این موتورها با انواع میکروکنترلرها ضروری است. بنابراین در این آموزش نحوه راه‌اندازی آن‌ها با میکروکنترلر Atmega16 مورد بررسی قرار می‌گیرد.

موتور DC چیست؟ 
به طور خاص، یک موتور DC برای تبدیل انرژی الکتریکی به انرژی مکانیکی از جریان DC استفاده می‌کند. اصل اساسی در یک موتور تعامل بین میدان مغناطیسی و جریان برای تولید نیرویی در داخل موتور است که به چرخش موتور کمک می کند. بنابراین وقتی جریان الکتریکی در میدان مغناطیسی از یک سیم پیچ عبور کند، نیروی مغناطیسی تولید شده که به دنبال آن گشتاور نیز تولید شده و موتور حرکت می‌کند. با تغییر جهت جربان جهت چرخش موتور و با تغییر ولتاژ تغذیه سرعت موتور نیز قابل کنترل است. از آنجا که میکروکنترلرها دارای قابلیت مدولاسیون عرض پالس (PWM ) هستند، بنابراین می توان از آن‌ها برای کنترل سرعت موتور استفاده کرد. در این آموزش عملکرد موتور DC با Atmega16 نشان داده می شود. درایور موتور L293D برای معکوس کردن جهت جریان و به دنبال آن جهت حرکت استفاده می شود. 

 

 

مواد اولیه :
# عنوان تعداد لینک
0 موتور DC 1 لینک خرید
1 میکروکنترلر Atmega 1 لینک خرید
2 درایور موتور ماژول ULN2003 / L293D 1 لینک خرید
3 اسیلاتور کریستالی 16 مگاهرتز 1 لینک خرید
4 برد بورد 1 لینک خرید
5 شستی فشاری 2 لینک خرید
6 خازن 100 نانو فاراد 2 لینک خرید
7 خازن 22 پیکو فاراد 2 لینک خرید
8 نشانگر LED 1 لینک خرید
9 سیم جامپر 1 لینک خرید

مرحله 1 : اتصالات و دیاگرام مداری

در این درایور  از مدار H-Bridge برای انتقال جریان به موتور استفاده می شود. از دو شستی فشاری برای انتخاب جهت حرکت موتور استفاده می شود. یکی از دکمه های فشار برای انتخاب جهت ساعتگرد و دیگری برای انتخاب حرکت در جهت پادساعتگرد در نظر گرفته شده است.

مرحله 2 : کدنویسی و تنظیمات نرم‌افزاری

در این آموزش از میکروکنترلر Atmega16 به عنوان واحد کنترل استفاده شده است. برنامه کامل در پایان پروژه آورده شده است.کافیست برنامه را روی میکرو کنترلر آپلود کرده و از دو شستی فشاری برای انتخاب جهت چرخش استفاده کنید. از  L293D به عنوان درایور نیز استفاده می‌شود. هنگام فشار دادن دکمه مربوطه، موتور DC از دو جهت می چرخد.

در گام اول مقدار فرکانس‌کاری CPU میکروکنترلر را مشخص کرده و کلیه کتابخانه‌های لازم را فراخوانی می‌شوند.

#define F_CPU 16000000UL    
#include<avr/io.h>
#include<util/delay.h>

سپس از یک متغیر برای ذخیره‌ی وضعیت شستی استفاده می‌شود. این متغیر برای تعریف جهت موتور نیز استفاده خواهد شد.

int i;

با استفاده از رجیستر جهت (Data Direction Register)، باید حالت ورودی / خروجی  GPIO را  مشخص شود. در ابتدا خروجی پین موتور Low شده تا از حرکت موتور در هنگامی که هیچکدام از شستی ها فشار داده نشده اند، جلوگیری شود.

DDRA = 03;  
PORTA &= ~(1<<1);
PORTA &= ~(1<<0);

وضعیت شستی اول که به پورت A4 متصل شده است، بررسی شده و در یک متغیر ذخیره می‌شود.

if(!bit_is_clear(PINA,4))
{
     i = 1;                     
     PORTA &= ~(1<<1);
     _delay_ms(1000);                                                           
}

در این مرحله وضعیت شستی دوم که به پورت A5 متصل شده است. بررسی شده و  در یک متغیر ذخیره می‌شود.

  else if (!bit_is_clear(PINA,5))  
     {
         i = 2;                                                         
         PORTA &= ~(1<<0);
        _delay_ms(1000);
     }

در صورت فعال شدن شستی 1 موتور DC ساعتگرد و در صورت فعال شدن شستی 2 موتور پادساعتگرد می چرخد.

if (i == 1)                   
{
    PORTA |= (1<<0);           
    PORTA &= ~(1<<1);
}
   else if (i == 2)        
 {
     PORTA |= (1<<1);           
     PORTA &= ~(1<<0);
 }

بسته به GPIO استفاده شده ، می توانید پین های موتور را به هر پین GPIO متصل کنید. همچنین استفاده از درایور برای کاهش بار محاسباتی روی میکروکنترلر بسیار مهم است. زیرا میکروکنترلرها قادر به تأمین جریان مورد نیاز برای موتورهای DC نیستند.

کد کامل پروژه:

#define F_CPU 16000000UL       //define cpu frequency
#include<avr/io.h>
#include<util/delay.h>
 
int i;        //define variable for comparison
int main(void)
{   
//DDR Data Direction Register
DDRA = 03;                        // make PORTA0,1 pin as Output and Rest as input
PORTA &= ~(1<<1);                // make PORTA1 pin low initially to avoid movement before push button selection
PORTA &= ~(1<<0); // make PORTA0 pin low initially to avoid movement before push button selection
 
while(1)
{
if(!bit_is_clear(PINA,4)) // check if PORTA4 push button is pressed
{
i = 1;               //store status as 1
PORTA &= ~(1<<1);
_delay_ms(1000);  
}
else if (!bit_is_clear(PINA,5))   // check if PORTA5 push button is pressed
{
  i = 2;                  //store status as 2
  PORTA &= ~(1<<0);
  _delay_ms(1000);
}
 
if (i == 1)              // if 1st button is pressed 
{
PORTA |= (1<<0); //rotate in clockwise direction
PORTA &= ~(1<<1);
}
else if (i == 2)         //if 2nd push button is prssed 
{
PORTA |= (1<<1); //rotate anticlock wise
PORTA &= ~(1<<0);
}
 
}
}