پروژه کنترل سرعت چرخش فن با توجه به دما – قسمت دوم
همانطور که در پست قبلی گفته شده است بیشترین جریانی که پورت های این میکروکنترلر avr میتواند داشته باشند ۴۰ میلی آپر است. پس نیاز است خروجی های این میکرو کنترلر تقویت شده و سپس به فن های مورد نظر متصل گردد. ما در این پروژه جهت تقویت خروجی های میکرو کنترلر از ترنزیستور ماسفت قدرت مدل php45n03lta استفاده شده که برای کلید زنی بسیار خوب است که توانای تحمل ولتاژ تا رنج ۳۰ ولت و جریان ماکزیمم ۴۵ آمپر را دارد.
یک مدار پیشنهادی جهت تقویت پورتهای میکرو کنترلر میتواند مانند تصویر زیر باشد.( فرض این پروژه استفاده از فن های dc 12 ولتی می باشد)
خروجی میکرو کنترلر منطقی است پس یا ۵ ولت است یا صفر ولت هنگامی که ولتاژ ۵ ولت به گیت داده شود مانند یک کلید بسته عمل میکند(در ناحیه اشباع قرار میگیرد) و باعث چرخش فن میشود. وقتی هم ولتاژ گیت آن صفر ولت باشد مانند یک کلید باز عمل میکند. جهت کنترل سرعت فن ها از PWM استفاده شده که در قسمت برنامه نویسی طرز کنترل این سرعت توضیح داده خواهد شد.
تغذیه مدار میکرو کنترلر و سنسور دما از طریق یک رگولاتور ۷۸۰۵ است که ورودی ۱۲ ولت را به ۵ ولت که ولتاژ مناسب برای میکرو کنترلر است تبدیل میکند.
شماتیک کلی مدار
برنامه نویسی میکرو کنترلر:
نرم افزار مورد استفاده codevision avr 3.12 می باشد . که از زبان برنامه نویسی C برای میکرو کنترلرهای avr پشتیبانی میکند.
با توجه به محبوبیت بالای این زبان برنامه نویسی این زبان را به کاربردی ترین زبان برنامه نویسی تبدیل نموده است که بدون اغراق تمام میکروکنترلرها را میتوان با این زبان برنامه نویسی نمود.
دیاگرام برنامه نوشته شده مانند زیر است.
پس توابع مورد نیاز ما میتواند مانند زیر باشند.
۱-تابع مقدار دهی اولیه به رجیستر های مبدل آنالوگ به دیجیتال:
void adc_init();
۲-تابعی که مقدار ولتاژی که به پایه شماره “input_pin” پورت A را میخواند و پاسخ را به ما بر میگرداند.
unsigned short int read_adc(unsigned char input_pin);
۳- تابعی که مقدار خوانده شده را از تابع بالا را تبدیل به دمای متناسب میکند و مقدار دما را به ما بر میگرداند.
float read_temp();
۴- تابع زیر برای مقدار دهی اولیه به تایمر صفر ایجاد شده(از تایمر صفر جهت تولید پالس در حالت pwm استفاده میکنیم.)
void Timer0_init();
۵- تابع وقفه سر ریز تایمر صفر هرگاه مقدار رجیستر TCNT0 با رجیستر OCR0 برابر شد این وقفه اجرا میشود.
interrupt [TIM0_OVF] void timer0_isr();
۶- تابع تنظیم عرض پالس ها ( این تابع مقدار متغییر pw را با توجه به دما تنظیم میکند؛ ما از این متغیر جهت تنظیم رجیستر OCR0 استفاده میکنیم.)
void set_pw();
۷- در این پروژه مقدار بیشنه دما را کاربر میتواند تنظیم کند که مثلا برای این محیط دما نهایتا میتواند ۶۰ درجه باشد. این تابع عمل تنظیم بیشترین دما را بر عهده دار و آن را در متغییر max_tmp ذخیره میکند.
void set_max_tmp();
توابع مربوط به مبدل آنالوگ به دیجیتال میکروکنترلر avr
نکته: در تابع زیر دو رجیستر ACSR, SFIOR که برای مقایسه کننده آنالوگ هستد را با این مقادیر داده غیر فعال نموده ایم ( این اطلاعات در دیتا شیت میکرو موجود است).
void adc_init()
{
ACSR=0x80;
SFIOR=0x00;
ADMUX=(1<<REFS1)|(1<<REFS0);//using internal 2.56v Voltage reference...
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);//Enable ADC with Prescalar=Fcpu/16
}
unsigned short int read_adc(unsigned char input_pin)
{
ADMUX |=(input_pin&(0x07))|(1<<REFS1)|(1<<REFS0);;
//Start Single conversion
ADCSRA|=(1<<ADSC);
//Wait for conversion to complete
while(!(ADCSRA & (1<<ADIF)));
//Clear ADIF by writing one to it
ADCSRA|=(1<<ADIF);
return (ADCW);
}
برای بدست آوردن دما ابتدا باید مقدار خوانده شده از تابع بالا را در فرمول زیر جایگزاری نمود. سپس پاسخ آن را در ۱۰۰ ضرب نمود تا دما بدست آید.(سنسور lm35 به ازای هر درجه سیلسیوس ۱۰ میلی ولت ولتاژ خروجی آن افزایش پیدا می کند.)
adc=(Vin*2.56)/1024
نکته : ۱۰۲۴ به این دلیل انتخاب شده که دقت عدد خوانده شده ۱۰ بیتی است در فرومول بالا Vin همان عدد ده بیتی است که در حالت ماکسیمم برابر ۲٫۵۶ ولت است. عدد ۲٫۵۶ ولت به عنوان ولتاژ رفرنس adc در نظر گرفته شده است…
float read_temp()
{
T=(read_adc(0)*2.56/1024)*100 ;
return T;
}
توابع مربوط به تایمر صفر میکروکنترلر avr به شرح زیر می باشد:
در تابع زیر تایمر صفر در حالت fast pwm و باتقسیم فرکانسی کلاک سیستم( که از یک کریستال خارجی ۱۰ مگاهرترتز تامین میشود) بر ۶۴ و فعال کردن وقفه سرریز مقدار دهی شده است.
void Timer0_init()
{
TCNT0=0x00;
TCCR0 |=(1<<CS00)|(1<<CS01) | (1<<WGM00)|(1<<WGM01)|(1<<COM01);//fcpu/64
TIMSK |= (1 << TOIE0);
DDRB=0xff;
}
دقت کنید که تغییر حالت پالس حاصل از این تایمر در رجیستر OCR0 ذخیره میشود. و پایه پورت PB3 یا همان OC0 پالس تولیدی از این رجیستر را در خود نمایش میده.(به همین دلیل فن اصلی را به این پایه وصل نموده ایم).
interrupt [TIM0_OVF] void timer0_isr()
{
static int delay=0;
TCNT0=0x00;
TCCR0=0x00;
if(delay++>=1000)
{
lcd_gotoxy(0,0);
sprintf(strLCD,">Temp=%0.2f ",T);
lcd_puts(strLCD);
lcd_putchar(0);lcd_putchar('C');
delay=0;
}
OCR0=PW;
TCCR0 |=(1<<CS00)|(1<<CS01) | (1<<WGM00)|(1<<WGM01)|(1<<COM01);//fcpu/64
}
همانطور که در تابع بالا قابل مشاهده هست با تنظیم متغییر PW به رجیستر OCR نسبت داده شده است.که باید یک عدد ۱ بایتی یعنی از ۰ تا ۲۵۵ باشد.این متغیردرواقع زمان وظیفه پالس را مشخص میکند.
جهت تنظیم خود متغییر pw نسبت به دمای خوانده شده و بیشنه دما مورد نظر از تابع زیر استفاده شده است.
در این تابع اگر ماکزیمم دما بیشتر از ۳ برابر دمای حال حاضر باشد فن ها را خاموش میکند. واگر بزرگتر از این عبارت و کوچکتر از ماکزیمم دما باشد جهت کنترل سرعت فن طول پالس را از رابطه زیر محاسبه میکند:
pw=( T/Max_tmp )*255
و درصورتی که دما بیش از اندازه مورد نظر ما باشد هردو فن با حد اکثر سرعت خود میچرخند.
Void set_pw()
{ if(T<=(Max_tmp/3))
{
PW=1;
Fan2=0;
}
else if(((Max_tmp/3)<T) && (T<Max_tmp) )
{
PW=(T/Max_tmp)*255;
Fan2=0;
}
else
{
PW=254;
Fan2=1;
}
}
ادامه دارد( در قسمت بعد پاسخ به : pwm چگونه سرعت موتور را کنترل میکند!؟ , سورس کامل پروژه ) . . .
دیدگاهتان را بنویسید