#ifndef F_CPU //jinak v makefile #define F_CPU 11059200 #endif #include #include #include #include /******************definice*****************/ //porty #define MOD PINA1 #define LED PINA2 #define ZVUK PINA3 #define PWM_R PINB3 #define UNIV_OUT PINB5 #define SD PIND6 #define PWM_L PIND7 //konstanty #define PERIODA 0x0FE //nemuze byt vic jak 0xFF (delka citace) #define STRED_DOLNI 46 //meze pro paku uprostred #define STRED_HORNI 54 #define MIN_NAPETI 0x228 //0x228 odpovida 2.7V na vstupu ADC, tzn. 9V pred delicem #define ZPOMALENI 60 //procenta zpomaleni oproti puvodni max. rychlosti //makra #define SETBIT(Adresa, Bit) (Adresa|=(1<STRED_DOLNI) nastav_motory(norm(plyn-smer), norm(plyn+smer)); else nastav_motory(norm(plyn+smer), norm(plyn-smer)); //nastav_motory(norm(fservo1), norm(fservo2)); //klasicky tankovy rizeni mezZvuk=(-1.6)*absrozdil(plyn, 50)+85; nastavit=FALSE; } if (zablokovano) if (zacatek>=100) //cca 0.5s od zapnuti zapnu motory a rozsvitim LED { zablokovano=FALSE; CLEARBIT(PORTA, LED); } if (mereni>=200) { mereni=0; low_bat=!zmer_napeti(); if (!zablokovano) { if (low_bat) preklop_led(); else CLEARBIT(PORTA, LED); } } if (citacZvuk>=mezZvuk) { citacZvuk=0; preklop_zvuk(); } } } /***********************************************/ /***********KONEC HLAVNIHO PROGRAMU*************/ /***********************************************/ /**************funkce***********/ /************************nastaveni otacek motoru*/ void nastav_motory(unsigned char proc_levy, unsigned char proc_pravy) { float proc, zpomal; if (CHECKBIT(PINA, MOD)) zpomal=ZPOMALENI; else zpomal=100; proc=50+((zpomal*(proc_levy-50))/100); mlevy.l=PERIODA*(1-(proc/100)); mlevy.h=0xFF-(PERIODA-mlevy.l); mlevy.l=0xFF-mlevy.l; proc=50+((zpomal*(proc_pravy-50))/100); mpravy.l=PERIODA*(1-(proc/100)); mpravy.h=0xFF-(PERIODA-mpravy.l); mpravy.l=0xFF-mpravy.l; } /*************************preruseni od timeru0, levy motor*/ ISR(TIMER0_OVF_vect) { if (CHECKBIT(PIND, PWM_L)) { CLEARBIT(PORTD, PWM_L); TCNT0=mlevy.l; } else { SETBIT(PORTD, PWM_L); TCNT0=mlevy.h; } } /*************************preruseni od timeru2, pravy motor*/ ISR(TIMER2_OVF_vect) { if (CHECKBIT(PINB, PWM_R)) { CLEARBIT(PORTB, PWM_R); TCNT2=mpravy.l; } else { SETBIT(PORTB, PWM_R); TCNT2=mpravy.h; } } /*************************preruseni od timeru1, toci furt dokolecka, per. preteceni 0,005925835503472s*/ ISR(TIMER1_OVF_vect) { if (servopulzy1<21) servopulzy1++; if (servopulzy2<21) servopulzy2++; if ((servopulzy1>20)||(servopulzy2>20)) { servo1=16589; //tzn. nemam signal priblizne 0.12s, 6 period servosignalu servo2=16589; servopulzy1=0; //aby sem neskakal furt servopulzy2=0; } if (aktualizace>=5) { nastavit=TRUE; aktualizace=0; } if (zacatek<100) zacatek++; aktualizace++; mereni++; citacZvuk++; } /*************************preruseni od servo1 - smer*/ ISR(INT0_vect) { unsigned int temp; GIFR=(1<=s1) servo1=temp-s1; else servo1=(0xFFFF-s1)+temp; //tzn. mezitim mi pretek citac CLEARBIT(MCUCR, ISC00); //spousteni sestupnou hranou, tzn. cekam na dalsi puls } } /*************************preruseni od servo2 - rychlost*/ ISR(INT1_vect) { unsigned int temp; GIFR=(1<=s2) servo2=temp-s2; else servo2=(0xFFFF-s2)+temp; //tzn. mezitim mi pretek citac CLEARBIT(MCUCR, ISC10); //spousteni sestupnou hranou, tzn. cekam na dalsi puls } } /********************************uprava na rozsah 0 az 100*/ unsigned char norm(float co) { if (co<0) return(0); if (co>100) return(100); return((unsigned char)co); } /*************************************absolutni rozdil*/ unsigned char absrozdil(unsigned char a, unsigned char b) { if (a>b) return(a-b); else return(b-a); } /*********************************stredova poloha vst. signalu*/ boolean_t stred(float signal) { if ((signal>=STRED_DOLNI)&&(signal<=STRED_HORNI)) return(TRUE); else return(FALSE); } /*******************************zmeri napeti baterky*/ boolean_t zmer_napeti(void) { ADMUX=0xC0; //reference AREF, kanal 0 ADCSRA=0x84; _delay_us(10); ADCSRA|=0x40; while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; ADCSRA|=0x40; //pro jistotu dva odmery, prvni nemusi byt ok while ((ADCSRA & 0x10)==0); ADCSRA|=0x10; if (ADCW<=MIN_NAPETI) return(FALSE); else return(TRUE); } /*******************preklopi ledku*/ void preklop_led(void) { if (CHECKBIT(PINA, LED)) CLEARBIT(PORTA, LED); else SETBIT(PORTA, LED); } /*******************preklopi zvuk. vystup*/ void preklop_zvuk(void) { if (CHECKBIT(PINA, ZVUK)) CLEARBIT(PORTA, ZVUK); else SETBIT(PORTA, ZVUK); }