به نام خدا
آموزش جامع avr جلسه ۱۱ : تو این جلسه از آموزش AVR میخوام در مورد PWM توضیح بدم که زیر مجموعه تایمر/کانتر هستش…..همون طور که میدونید تو تایمر/کانتر چندید مد داریم که مد PWM یکی از این مد ها هستش…..به PWM هم بعضا DAC هم گفته میشه….یعنی به وسیله PWM یا DAC ما میایم و با میکروکنترلر avr ولتاژ ۰ تا ۵ ولت رو درست میکنیم….که مثلا برای کنترل نور یه LED میتونیم از PWM استفاده کنیم و با کم و زیاد کردن ولتاژ میتونیم شاهد تغییر نور LED رو کم و زیاد کنیم یا بازم مثلا (!) تو کنترل سرعت موتور های DC میشه ازش استفاده کرد…..همون طور که (انشاالله) میدونید سرعت موتور های DC وابسته به میزان ولتاژ اعمالی به اون ها هستش…یعنی هر چی ولتاژ بیشتر بهش بدیم سرعتش بیشتر و هر چی ولتاژ کمتر بدیم سرعت موتور DC کمتر میشه…….امید وارم کاربرد این مطلبی که انشاالله میخوام در ادامه توضیح بدم رو فهمیده باشید( البته اگه متوجه نشدید بگید تا بیشتر توضیح بدم….)
انواع تایمر/کانتر در avr
تو avr و تو میکرو کنترلر مگا ۱۶ ما ۳ تا تایمر کانتر داریم که به اولی میگن “تایمر/کانتر ۸ بیتی صفر” و به دومی میگن “تایمر کانتر ۱۶ بیتی ۱” و به سومی میگن “تایمر کانتر ۸ بیتی ۲”
پس ۲ تا تایمر/کانتر ۸ بیتی داریم و یه دونه ۱۶ بیتی……
آموزش کار با DAC یا همون PWM در AVR
همون طور که تو عکس زیر میبینید تو میکروکنترلر avr یه ۴ تا پایه هستش که میشه به عنوان پایه های pwm یا همون DAC ازشون استفاده کرد…..مثلا اگه از تایمر کانتر ۸ بیتی ۰ یا ۲ استفاده کنید فقط یه پایه برای این کار وجود داره(هر تایمر یه دونه پایه) ولی تو تایمر/کانتر ۱۶ بیتی ۱ دو پایه به برای این کار وجود داره….که ما تو کنترل سرعت موتور مخصوصا برا ساخت ربات ها که معمولا به ۲ موتور و ۲ چرخ برا رباتشون نیاز دارن میان و از تایمر/کانتر ۱۶ بیتی ۱ استفاده میکنن تا سرعت ۲ تا موتور رو کنترل کنن….لذا دیگه از تایمر ۰ یا ۲ استفاده نمیکنن….
توجه ۱ : تایمر کانتر ۰ و ۲ هشت بیتی هستن و تایمر/کانتر ۱ شانزده بیتی هستش.
توجه ۲ : تو حالت ۸ بیت ماکزیمم مقدار۰XFF هستش که یعنی ۲۵۶ و تو حالت ۱۶ بیت ماکزیمم مقدار ۰XFFFF هستش که یعنی ۶۵۵۳۶ ولی باید توجه کرد که چون شمارش کلاک (و کلا شمارش هر چیزی تو AVR ) از صفر شروع میشه و نه یک ، لذا تو حالت ۸ بیت ماکزیمم مقدار ۲۵۵ هستش و تو حالت ۱۶ بیت ماکزیمم مقدار ۶۵۵۳۵ هستش.
ریجسترهای تایمر/کانتر
من حال توضیح دادن رو ندارم….جسله قبلی(جلسه۹) هم ریجستر ها رو توضیح ندادم….یه سایت هست که خوب توضیح داده…من لینک های اونو قرار میدم….شما برید ریجستر هاش رو بخونید….و من این جا چند تا پروژه ساده قرار میدم براتون.
جلسه۱ جلسه۲ جلسه۳ جلسه۴ جلسه۵ جلسه۶ جلسه۷ جلسه۸
منم در زیر سه تا پروژه ساده با هر کدوم از سه تا تایمر/کانتر موجود رو براتون میزارم.
پروژه کنترل دور موتور DC
پروژه avr یک ، با تایمر/کانتر صفر
مدار پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <mega16.h> #include <stdlib.h> #include <delay.h> #asm .equ __lcd_port=0x12 ;PORTD #endasm #include <lcd.h> void main(void) { int x=150; char str[10]; DDRB=0X08; //تعیین پایه مقابل به عنوان خروجی OCR0(PORTB.3) DDRA=0X00; // Timer/Counter 0 initialization // Clock source: System Clock _ f/256 // OC0 output: Clear OC0 on compare match,Set OC0 at TOP // Mode: FAST PWM TCCR0=0b01101100;//با افزایش مقدار داده شده-سرعت زیاد میشه //TCCR0=0b01111100;//با افزایش مقدار داده شده-سرعت کم میشه TCNT0=0x00;//محتوای ۸ بیتی تایمر کانتر درش ذخیره میشه OCR0=0x00;//مبنای مقایسه رو در مد مقابل تعیین میکند PWM TIMSK=0x00;// Timer(s)/Counter(s) Interrupt(s) initialization TIFR=0x00; lcd_init(16); lcd_gotoxy(0,0);lcd_puts(" PWM & TIMER0"); while (1) { if(PINA.0)x=x+30; else if(PINA.1)x=x-30; if(x<0)x=0; else if(x>255)x=255; itoa(x,str); lcd_gotoxy(6,1);lcd_puts(str);lcd_puts(" "); OCR0=x; delay_ms(200); }; } |
پروژه avr دو ، با تایمر/کانتر دو
کدهای پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#include <mega16.h> #include <stdlib.h> #include <delay.h> #asm .equ __lcd_port=0x15 ;PORTC #endasm #include <lcd.h> void main(void) { int x=150; char str[10]; DDRD=0X80; //تعیین پایه مقابل به عنوان خروجی OCR2(PORTD.7) DDRA=0X00; // Timer/Counter 2 initialization // Clock source: System Clock _ f/256 // OC0 output: Clear OC0 on compare match,Set OC0 at TOP // Mode: FAST PWM TCCR2=0b01101110;//با افزایش مقدار داده شده-سرعت زیاد میشه //TCCR2=0b01111110;//با افزایش مقدار داده شده-سرعت کم میشه TCNT2=0x00;//محتوای ۸ بیتی تایمر کانتر درش ذخیره میشه OCR2=0x00;//مبنای مقایسه رو در مد مقابل تعیین میکند PWM ASSR=0x00; TIMSK=0x00;// Timer(s)/Counter(s) Interrupt(s) initialization TIFR=0x00; lcd_init(16); lcd_gotoxy(0,0);lcd_puts(" PWM & TIMER2"); while (1) { if(PINA.0)x=x+30; else if(PINA.1)x=x-30; if(x<0)x=0; else if(x>255)x=255; itoa(x,str); lcd_gotoxy(6,1);lcd_puts(str);lcd_puts(" "); OCR2=x; delay_ms(200); }; } |
پروژه avr سه ، با تایمر/کانتر یک
کدهای پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <mega16.h> #include <stdlib.h> #include <delay.h> #asm .equ __lcd_port=0x15 ;PORTC #endasm #include <lcd.h> void main(void) { int x=150; char str[10]; DDRD=0XFF;//تعیین پایه های مقابل ب عنوان خروجی OCR1A-OCR1B DDRA=0X00; // Timer/Counter 1 initialization // Clock source: System Clock _ f/256 // Clear OCR1A/PCR1B on compare match,Set OCR1A/PCR1B at TOP // Mode: FAST PWM _ TOP=OCR1A TCCR1A=0xA3; TCCR1B=0x04; TCNT1=0x00;//محتوای ۱۶ بیتی تایمر کانتر درش ذخیره میشه OCR1A=0x00;//مبنای مقایسه رو در مد مقابل تعیین میکند PWM OCR1B=0x00;//مبنای مقایسه رو در مد مقابل تعیین میکند PWM TIMSK=0x00;// Timer(s)/Counter(s) Interrupt(s) initialization TIFR=0x00; lcd_init(16); lcd_gotoxy(0,0);lcd_puts(" PWM & TIMER1"); while (1) { if(PINA.0)x=x+50; else if(PINA.1)x=x-50; if(x<0)x=0; else if(x>1023)x=1023; itoa(x,str); lcd_gotoxy(6,1);lcd_puts(str);lcd_puts(" "); OCR1A=x; OCR1B=x; delay_ms(200); }; } |
پروژه هایی با تایمر در مد FAST PWM
توجه خیلی مهم : سه پروژه بالا رو من اصلا خوشم نمیاد، اگه از من میشنوید نگاشون هم نکینید در عوض پروژه های زیر رو ببینید که با هر سه تایمر نوشتم و هم کد هاش ساده هستش و هم اصولی و درست و حسابی
کنترل دور موتور DC با FAST PWM و تایمر ۰
اینم از کدهای پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <mega16.h> #include <delay.h> void main(void) { int i=0; //تعیین پایه مقابل به عنوان خروجی OCR0(PORTB.3) DDRB = (0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (1<<DDB3) | (0<<DDB2) | (1<<DDB1) | (1<<DDB0); PORTB = (0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0); // TIMER0 // Clock Timer0 = CLK/64 >>>>> CS00 = 1, CS01 = 1, CS02 = 0 // Mode = Fast PWM >>>>> WGM00 = 1, WGM01 = 1 // Clear OC0 on compare match, set OC0 at BOTTOM >>>>> COM00 = 0, COM01 = 1 TCCR0 = (0<<FOC0) | (1<<WGM00) | (1<<COM01) | (0<<COM00) | (1<<WGM01) | (0<<CS02) | (1<<CS01) | (1<<CS00); //TIMSK = (0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0); //TIFR = (0<<OCF2) | (0<<TOV2) | (0<<ICF1) | (0<<OCF1A) | (0<<OCF1B) | (0<<TOV1) | (0<<OCF0) | (0<<TOV0); TCNT0 = 0; OCR0 = 0; while (1) { // افزایش سرعت و چپ گرد PORTB.0 = 1; PORTB.1 = 0; for(i=0; i<=255; i=i+50) { OCR0 = i; delay_ms(1000); } // کاهش سرعت و راست گرد PORTB.0 = 0; PORTB.1 = 1; for(i=255; i>=0; i=i-50) { OCR0 = i; delay_ms(1000); } }; } |
برا بحث نحوه مقدار دهی پورت ها و ریجستر ها میتونید مطلب مقابلرو بخونید : آموزش صحیح و خوانا نوشتن کد
بحث ریجستر ها هم میتونید اون لینک های بالا رو بخونید و یا این که تو مطالب بعد خودم توضیحشون میدم.
کنترل دور موتور DC با FAST PWM و تایمر ۱
اینم از کدهای پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <mega16.h> #include <delay.h> void main(void) { int i=0; //تعیین پایه های مقابل ب عنوان خروجی OCR1A-OCR1B //خروجی تعریف کردن ۴ بیت اول پورت دی-برا کنترل جهت چرخش موتور DDRD = (0<<DDD7) | (0<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0); PORTD = (0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0); // TIMER1 // Clock Timer2 = CLK/64 >>>>> CS10 = 1, CS11 = 1, CS12 = 0 // Mode = Fast PWM 10bit=1023 >>>>> WGM10 = 1, WGM11 = 1, WGM12 = 1, WGM13 = 0 // Clear OC1A/OC1B on compare match, set OC1A/OC1B at BOTTOM, >>>>> COM1A0_COM1B0 = 0, COM1A1_COM1B1 = 1 TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<FOC1A) | (0<<FOC1B) | (1<<WGM11) | (1<<WGM10); TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (1<<CS11) | (1<<CS10); //TIMSK = (0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0); //TIFR = (0<<OCF2) | (0<<TOV2) | (0<<ICF1) | (0<<OCF1A) | (0<<OCF1B) | (0<<TOV1) | (0<<OCF0) | (0<<TOV0); TCNT1 = 0; OCR1A = 0; OCR1B = 0; while (1) { // تعیین سرعت و جهت چرخش موتور ها PORTD.0 = 1; PORTD.1 = 0; PORTD.2 = 0; PORTD.3 = 1; for(i=0; i<=1023; i=i+250) { OCR1A = i; OCR1B = i; delay_ms(1000); } // تعیین سرعت و جهت چرخش موتور ها PORTD.0 = 0; PORTD.1 = 1; PORTD.2 = 1; PORTD.3 = 0; for(i=1023; i>=0; i=i-250) { OCR1A = i; OCR1B = i; delay_ms(1000); } }; } |
کنترل دور موتور DC با FAST PWM و تایمر ۲
اینم از کدهای پروژه
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#include <mega16.h> #include <delay.h> void main(void) { int i=0; //تعیین پایه مقابل به عنوان خروجی OCR2(PORTD.7) //خروجی کردن بیت های ۰ و ۱ پورت دی برا کنترل جهت موتور DDRD = (1<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (1<<DDD1) | (1<<DDD0); PORTD = (0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0); // TIMER2 // Clock Timer2 = CLK/64 >>>>> CS20 = 1, CS21 = 1, CS22 = 0 // Mode = Fast PWM >>>>> WGM20 = 1, WGM21 = 1 // Clear OC0 on compare match, set OC0 at BOTTOM >>>>> COM20 = 0, COM21 = 1 TCCR2 = (0<<FOC2) | (1<<WGM20) | (1<<COM21) | (0<<COM20) | (1<<WGM21) | (0<<CS22) | (1<<CS21) | (1<<CS20); //TIMSK = (0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<OCIE0) | (0<<TOIE0); //TIFR = (0<<OCF2) | (0<<TOV2) | (0<<ICF1) | (0<<OCF1A) | (0<<OCF1B) | (0<<TOV1) | (0<<OCF0) | (0<<TOV0); //ASSR = (0<<AS2) | (0<<TCN2UB) | (0<<OCR2UB) | (0<<TCR2UB); TCNT2 = 0; OCR2 = 0; while (1) { // افزایش سرعت و چپ گرد PORTD.0 = 1; PORTD.1 = 0; for(i=0; i<=255; i=i+50) { OCR2 = i; delay_ms(1000); } // کاهش سرعت و راست گرد PORTD.0 = 0; PORTD.1 = 1; for(i=255; i>=0; i=i-50) { OCR2 = i; delay_ms(1000); } }; } |
خوب این جلسه هم تموم شد، اگه سوالی بود حتما حتما بپرسید، تا حد توان پاسختون رو میدم.
در ضمن ممنون از دوستانی که اشتباهات تایپی/علمی و… رو بهم میگن.
فعلا یا علی.
مهمان
سلام.
دمت گرم با آموزش ها
فقط یه چیزی من پروژه دانشگاهیم با استفاده از PWM هست، آموزش های شما و وبلاگ نویز رو خوندم، ولی خیلی متوجه نشدم، تایمر کانتر رو بهتر توضیح داده بودی
مهمان
سلام.
فرمولی هست که ولتاژه تو بدی عدد ریجیسترOCRxبگیری؟
مهمان
سلام.

ممنون پروزه های باهالی میزاری
با یکم تعغیر کد ها میشه تر کیب رنگ درست کرد
مهمان
سلام.
با تشکر از اینکه علمتون رو در اختیار بقیه هم می گزارید.فقط ازتون می خوام که برا افرادی مث من که خیلی پایه هستم یکم پایه ای تر توضیح بدید. بازم ممنون.
نویسنده این مطلب
سلام
والا فک کنم تقریبا تو همه مطلب من میگم اگه سوالی چیزی اگه بد گفتم اگه توضیح بیشتر میخواست و…. بهم بگید
آخه من نمیدونم باید چطوری بگم و چیا رو بگم تا دوستان مبتدی به مشکل بر نخورن
چون شما وقتی مبتدی باشی و بخوای یه چیزو کار کنی کوچک ترین چیز هم برات مهم میشه
ولی وقتی اون چیزو یاد گرفتی میبینی اونایی که مشکل داشتی خیلی سادس و به مشکلات بزرگتری بر میخوری و …
و همنی وطر که پیشرفت میکنی مشکلات و چیزای ساده برات عادی میشن
انگار که جزو چیزای بدیهی هستش
و اون موقع اگه بخوای اون مطلب رو به دیگران یاد بدی قطعا یه سری چیزا رو نمیگی
نه این که نخوای بگی و یا حوصله نداشته باشی …. نه … چون اصلا یادت نیست، حواست نیست که اینا رو بگی و…
امیدوارد منظورمو متوجه شده باشی و این که ما کوچیک شما هستیم و چیزی هم بارمون نیست و اگه چیزی هم بلدیم از اساتید یاد گرفتیم و همونو میزاریم سایت و… (گفتم شاید از خوندن متن بالا … بگذریم)
در کل شما بگید کجا رو بیشتر توضیح بدم بنده در خدمتم.
مهمان
آقا دمه شما گرم با این سایته خوبتون
جسارت نباشه ولی توجه ۲ یه ایراد کوچولو داره اوونم اینه که ۰XFFFF میشه ۶۵۵۳۵
نویسنده این مطلب
بله درسته….اشتباه نوشتم
ممنون از شما
مهمان
میشه که بدون درایو یا همون ال 298 موتور دی سی رو راه انداخت ؟
نویسنده این مطلب
سلام
بله میشه ولی به شرطی که منبع تغزیت درست و حسابی باشه و برای زمان کم و فقط راه اندازی موتور و نه کار دیگه ای
مهمان
سلام.
میشه ترانزیستورم این کارو کرد.
مهمان
باورت میشه اقا مهدی بهترین سایتو داری .

اگه از اموزش هایی که میزاری یه فایل پی دی اف بزاری دقیقا همینایی که توی سایت به عنوان مثال توی عمین صفحه هستش عالی میشه . دیگه چیزی از استادی کم نمی زاری برامون .
مهمان
سلام
ممنون خیلی خوب بود.
آقا مهدی درباره کپچر avr برنامه ای دارین؟
اگه امکانش هست یه مقدار توضیح بدین با یه پروژه باشه که فقط با نحوه برنامه نویسیش و طرز کارش آشنا بشم.
اگه منبعی هم معرفی کنید ممنون میشم.
یا علی.
نویسنده این مطلب
سلام
منبعی جز گوگل سراغ ندارم.
مهمان
سلام
واقعا کارت درسته داداش
خدا خیرت بده
امیدوارم موفق باشی
خداخیرت بده
ممنون
مهمان
من نظر دادم
فقط ایمیلو اشتباهی وارد کردم.
مهمان
سلام
خسته نباشی داداش
واقعا دمتگرم
خدا خیرت بده و موفق باشی.
ممنون
مهمان
دمت گرم .
آموزش کار با AVR studio هم بزارید
نویسنده سایت
خیلی باحاله … ممنون آقا مهدی…