در این پست از سایت اِمیک, یک پروژه بسیار جالب و آموزشی به نام پروژه AVR کنترل روشنایی LED با جوی استیک قرار داده شده است. همانطور که از نام پروژه مشخص است, ما در این پروژه به وسیله میکروکنترلر AVR میزان روشنایی (یا درخشندگی) چهار عدد LED را توسط یک ماژول جوی استیک کنترل خواهیم کرد. در ادامه در مورد پروژه بیشتر توضیح خواهم داد. در زیر شماتیک این پروژه را مشاهده می کنید:
همانطور که مشاهده می کنید, ما در این پروژه از میکروکنترلر ATmega16 استفاده کرده ایم. از یک ماژول جوی استیک نیز استفاده کرده ایم که پایه های آن به صورتی که در ادامه می گویم به میکروکنترلر متصل شده است. پایه VRY ماژول به پین 0 از پورت A میکرو (پایه 40 میکرو), پایه VRX به پین 1 از پورت A میکرو (پایه 39 میکرو) و پایه های 5V+ و GND ماژول نیز به ترتیب به مثبت و منفی تغذیه 5 ولت متصل می شوند.
از چهار عدد LED به همراه چهار مقاومت نیز استفاده کرده ایم. مقاومت ها برای محدود کردن جریان مصرفی LED ها و جلوگیری از آسیب به آنها می باشند. ال ای دی مشخص شده با عبارت LED-F به پین 3 از پورت B (پایه 4 میکرو), LED-B به پین 7 از پورت D (پایه 21 میکرو), LED-R به پین 5 از پورت D (پایه 19 میکرو) و LED-L نیز به پین 4 از پورت D (پایه 18 میکرو) متصل شده است. پایه کاتد همه LED ها نیز به منفی تغذیه (GND) متصل می شود.
عملکرد پروژه بالا به این صورت است که اهرم جوی استیک را به هر سمتی که حرکت دهیم, LED که در آن جهت است روشن می شود. در صورت حرکت اهرم جوی استیک به سمت جلو LED-F روشن می شود, حرکت اهرم به سمت عقب LED-B روشن می شود, حرکت اهرم به سمت راست LED-R روشن می شود و در صورت حرکت اهرم جوی استیک به سمت چپ LED-L روشن خواهد شد.
روشن شدن LED ها به تدریجی و با توجه مقدار حرکت اهرم جوی استیک می باشد. یعنی هر چه که اهرم را به یک سمت بیشتر حرکت دهیم, نور LED آن سمت نیز بیشتر خواهد شد. در انتهای مطلب کلیپ تست پروژه را می توانید مشاهده کنید.
پایه 10 میکرو به مثبت تغذیه و همچنین پایه های 30 و 32 میکرو نیز به دلیل استفاده از ADC میکرو به مثبت تغذیه 5 ولت متصل شده اند. خازن ها نیز برای حذف نویز و نوسان تغذیه استفاده شده اند و باید در فاصله بسیار نزدیک به پایه های میکرو متصل شوند. پایه های 11 و 31 نیز به منفی تغذیه یا GND متصل می شوند.
برنامه کدویژن:
در این پروژه فرکانس میکروکنترلر 1 مگاهرتز تنظیم شده است. در زیر برنامه نوشته شده به زبان C و کامپایلر کدویژن را مشاهده می کنید:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
////////// WWW.EMIC.IR ////////// #include <mega16a.h> //معرفي کتابخانه ميکروکنترلر مگا 16// #include <delay.h> //delay معرفي کتابخانه// //ايجاد مي شوند adc که توسط خود کدويژن با فعالسازي adc از خط 6 تا 15 دستورات مربوط به// #define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR)) unsigned int read_adc(unsigned char adc_input) { ADMUX=adc_input | ADC_VREF_TYPE; delay_us(10); ADCSRA|=(1<<ADSC); while ((ADCSRA & (1<<ADIF))==0); ADCSRA|=(1<<ADIF); return ADCW; } void main(void) { int VRx=0, VRy=0; //در روبرو تعدادي متغير براي استفاده در برنامه تعريف شده است// //ورودي شده است ADC ميکرو براي استفاده از A در زير پورت// DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0); PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0); //ميکرو که خروجي تايمر صفر است خروجي شده است B در زير پين 3 از پورت// DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (1<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0); PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0); //و تايمر دو هستند خروجي شده اند A و تايمر يک B که به ترتيب خروجي هاي تايمر يک D در زير پين هاي 4 و 5 و 7 از پورت// DDRD=(1<<DDD7) | (0<<DDD6) | (1<<DDD5) | (1<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0); PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0); //از خط 39 تا 41 تنظيمات واحد تايمر/کانتر 0 ميکرو مي باشند که با توجه به تنظيمات ما در محيط کدويزارد ايجاد مي شوند// //در زير مي توانيد توضيحات مربوط به تنظيمات رجيسترهاي تايمر/کانتر 0 ميکرو را مشاهده کنيد// // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125/000 kHz // Mode: Phase correct PWM top=0xFF // OC0 output: Non-Inverted PWM // Timer Period: 4/08 ms // Output Pulse(s): // OC0 Period: 4/08 ms Width: 0 us TCCR0=(1<<WGM00) | (1<<COM01) | (0<<COM00) | (0<<WGM01) | (0<<CS02) | (1<<CS01) | (0<<CS00); TCNT0=0x00; OCR0=0x00; //از خط 60 تا 69 تنظيمات واحد تايمر/کانتر 1 ميکرو مي باشند که با توجه به تنظيمات ما در محيط کدويزارد ايجاد مي شوند// //در زير مي توانيد توضيحات مربوط به تنظيمات رجيسترهاي تايمر/کانتر 1 ميکرو را مشاهده کنيد// // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 125/000 kHz // Mode: Ph. correct PWM top=0x00FF // OC1A output: Non-Inverted PWM // OC1B output: Non-Inverted PWM // Noise Canceler: Off // Input Capture on Falling Edge // Timer Period: 4/08 ms // Output Pulse(s): // OC1A Period: 4/08 ms Width: 0 us // OC1B Period: 4/08 ms Width: 0 us // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=(1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (1<<WGM10); TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (1<<CS11) | (0<<CS10); TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; //از خط 80 تا 83 تنظيمات واحد تايمر/کانتر 2 ميکرو مي باشند که با توجه به تنظيمات ما در محيط کدويزارد ايجاد مي شوند// //در زير مي توانيد توضيحات مربوط به تنظيمات رجيسترهاي تايمر/کانتر 2 ميکرو را مشاهده کنيد// // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: 125/000 kHz // Mode: Phase correct PWM top=0xFF // OC2 output: Non-Inverted PWM // Timer Period: 4/08 ms // Output Pulse(s): // OC2 Period: 4/08 ms Width: 0 us ASSR=0<<AS2; TCCR2=(1<<PWM2) | (1<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (1<<CS21) | (0<<CS20); TCNT2=0x00; OCR2=0x00; //که با توجه به تنظيمات ما در محيط کدويزارد ايجاد مي شوند adc از خط 89 تا 91 رجيسترهاي مربوط به// // ADC initialization // ADC Clock frequency: 500/000 kHz // ADC Voltage Reference: AVCC pin // ADC Auto Trigger Source: ADC Stopped ADMUX=ADC_VREF_TYPE; ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0); SFIOR=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0); while (1) { VRy=read_adc(0); //VRy ميکرو که عددي بين 0 تا 1023 مي تواند باشد و ريختن ان در متغير A خواندن مقدار ولتاژ انالوگ روي پين 0 از پورت// VRx=read_adc(1); //VRx ميکرو که عددي بين 0 تا 1023 مي تواند باشد و ريختن ان در متغير A خواندن مقدار ولتاژ انالوگ روي پين 1 از پورت// //هاي متصل به خروجي اين تايمرها را تغيير دهيمLED با عددي بين حداقل 0 تا حداکثر 255 مي توانيم ميزان روشنايي OCR0,OCR2,OCR1A,OCR1B در ادامه ما با مقدار دهي رجيسترهاي// if (VRx >= 600) { //بيشتر از 600 شده و شرط روبرو اجرا مي شود VRx در صورتي که اهرام جوي استيک را به سمت جلو حرکت دهيم مقدار// OCR0=(VRx-600)/1.658; //را مقدار دهي مي کند OCR0 را به بازه 0 تا 255 تبديل مي کند و رجيستر VRx دستور روبرو مقدار متغير// } else { OCR0=0; //سمت جلو خاموش مي شود LED صفر مي شود که در نتيجه OCR0 بالا برقرار نبود رجيستر if در صورتي که شرط// } if (VRx <= 450) { //کمتر از 450 شده و شرط روبرو اجرا مي شود VRx در صورتي که اهرام جوي استيک را به سمت عقب حرکت دهيم مقدار// OCR2=(450-VRx)/1.764; //را مقدار دهي مي کند OCR2 را به بازه 0 تا 255 تبديل مي کند و رجيستر VRx دستور روبرو مقدار متغير// } else { OCR2=0; //سمت عقب خاموش مي شود LED صفر مي شود که در نتيجه OCR2 بالا برقرار نبود رجيستر if در صورتي که شرط// } if (VRy >= 600) { //بيشتر از 600 شده و شرط روبرو اجرا مي شود VRy در صورتي که اهرام جوي استيک را به سمت راست حرکت دهيم مقدار// OCR1A=(VRy-600)/1.658; //را مقدار دهي مي کند OCR1A را به بازه 0 تا 255 تبديل مي کند و رجيستر VRy دستور روبرو مقدار متغير// } else { OCR1A=0; //سمت راست خاموش مي شود LED صفر مي شود که در نتيجه OCR1A بالا برقرار نبود رجيستر if در صورتي که شرط// } if (VRy <= 450) { //کمتر از 450 شده و شرط روبرو اجرا مي شود VRy در صورتي که اهرام جوي استيک را به سمت چپ حرکت دهيم مقدار// OCR1B=(450-VRy)/1.764; //را مقدار دهي مي کند OCR1B را به بازه 0 تا 255 تبديل مي کند و رجيستر VRy دستور روبرو مقدار متغير// } else { OCR1B=0; //سمت چپ خاموش مي شود LED صفر مي شود که در نتيجه OCR1B بالا برقرار نبود رجيستر if در صورتي که شرط// } } } |
توضیحات قسمت های مهم برنامه نوشته شده, اگر سوالی داشتید می توانید در قسمت نظرات مطرح کنید. از انتهای مطلب نیز می توانید فایل برنامه این پروژه با نرم افزار کدویژن را دانلود کنید.
کلیپ تست عملی پروژه :
پسورد فایل زیپ : www.emic.ir
نظر یادتون نره…