main.cpp

См. документацию.
00001 
00029 #include <inttypes.h>
00030 #include <avr/io.h>
00031 #include <avr/interrupt.h>
00032 #include <stdlib.h>
00033 #include <util/delay.h>
00034 
00035 // назначение определений для удобства работы с периферией
00036 #define PORTOUT     PORTB
00037 #define DDROUT      DDRB
00038 #define PINOUT      PINB
00039 #define MOTOR_F     PB5
00040 #define MOTOR_B     PB3
00041 #define TURN_L      PB4
00042 #define TURN_R      PB2
00043 #define IRLED       PB1
00044 
00045 #define PORTIN      PORTD
00046 #define DDRIN       DDRD
00047 #define PININ       PIND
00048 #define LIGHT_R     PD0
00049 #define LIGHT_L     PD1
00050 #define BUMPER_F    PD3
00051 
00052 #define SBI(port,bit)  port |=  (1<<(bit))
00053 #define CBI(port,bit)  port &= ~(1<<(bit))
00054 
00055 // #define outb(port,bit)  port = bit
00056 //<- отказаться! <-Почему?
00057 //<- а смысл истользовать устаревший макрос?, тем более что он ни где не используется
00058 
00060 typedef enum {STOP=0, F, FR, FL, B, BR, BL} direction_t;
00061 const unsigned int TIME=1;
00062 
00063 // #define F_CPU 4000000
00064 //<- задать это ключем при компиляции -DF_CPU=4000000UL , это впринципе можно и так оставить?
00065 //<- нет это должно быть указано в Makefile, иначе _delay_(.*) не будет работать правильно
00066 
00071 unsigned char p[7][7] = {
00072     {14,    43,   57,   71,     7,      100,    100},
00073     {7,     43,   71,   100,    100,    100,    100},
00074     {7,     50,   93,   100,    100,    100,    100},
00075     {7,     50,   57,   100,    100,    100,    100},
00076     {29,    29,   29,   29,     57,     79,     100},
00077     {36,    36,   36,   36,     71,     93,     100},
00078     {36,    36,   36,   36,     71,     79,     100},
00079 };
00080 
00081 
00083 direction_t this_move;
00084 //unsigned char this_move;
00085 
00089 void go(direction_t direction){
00090     switch (direction) {
00091     case STOP:
00092         CBI(PORTOUT, MOTOR_F);
00093         CBI(PORTOUT, MOTOR_B);
00094         CBI(PORTOUT, TURN_R);
00095         CBI(PORTOUT, TURN_L);
00096         break;
00097 
00098     case F:
00099         SBI(PORTOUT, MOTOR_F);
00100         CBI(PORTOUT, MOTOR_B);
00101         CBI(PORTOUT, TURN_R);
00102         CBI(PORTOUT, TURN_L);
00103         break;
00104 
00105     case FR:
00106         SBI(PORTOUT, MOTOR_F);
00107         CBI(PORTOUT, MOTOR_B);
00108         SBI(PORTOUT, TURN_R);
00109         CBI(PORTOUT, TURN_L);
00110         break;
00111 
00112     case FL:
00113         SBI(PORTOUT, MOTOR_F);
00114         CBI(PORTOUT, MOTOR_B);
00115         CBI(PORTOUT, TURN_R);
00116         SBI(PORTOUT, TURN_L);
00117         break;
00118 
00119     case B:
00120         CBI(PORTOUT, MOTOR_F);
00121         SBI(PORTOUT, MOTOR_B);
00122         CBI(PORTOUT, TURN_R);
00123         CBI(PORTOUT, TURN_L);
00124         break;
00125 
00126     case BR:
00127         CBI(PORTOUT, MOTOR_F);
00128         SBI(PORTOUT, MOTOR_B);
00129         SBI(PORTOUT, TURN_R);
00130         CBI(PORTOUT, TURN_L);
00131         break;
00132 
00133     case BL:
00134         CBI(PORTOUT, MOTOR_F);
00135         SBI(PORTOUT, MOTOR_B);
00136         CBI(PORTOUT, TURN_R);
00137         SBI(PORTOUT, TURN_L);
00138         break;
00139     }
00140 }
00141 
00145 direction_t next_move(void){
00146     unsigned char pp,
00147     direction_t i;
00148 
00149     // получаем случайное число 0..99
00150     pp = rand()/327;
00151     // ищем соответствие в таблице вероятностей
00152     for (i=STOP; i < BL+1; i++) {
00153         if (p[this_move][i] > pp)
00154             break;
00155     }
00156     this_move = i;       // записываем новое полученное направление как текущее
00157     return(i);
00158 }
00159 
00163 inline void walk(void){
00164     // этот цикл организует "свободное блуждание" пока
00165     // нет сигнала ни от одного из датчиков освещенности
00166     while ( (bit_is_set(PININ, LIGHT_R)) && (bit_is_set(PININ, LIGHT_L)) ) {
00167         // получаем следующее направление движения и
00168         go(next_move());
00169         delay_ms(2500); 
00170     }
00171     
00172     for (int i=0; i < 10; i++) {
00173         _delay_loop_1(TIME);
00174         CBI(PORTOUT, IRLED);    // включаем ИК светодиод
00175         _delay_loop_1(TIME);
00176         SBI(PORTOUT, IRLED);    // выкл ИК светодиод
00177     }
00178     
00179     for (int u=0; u < 14; u++){
00180         int count=0;
00181         // если есть сигнал на Ик приемнике
00182         if (bit_is_clear(PININ, LIGHT_L)) {
00183             count++;
00184             if (count == 14) {
00185                 if (this_move == FR)
00186                     go(BL);
00187                 if (this_move == FL)
00188                     go(BR);
00189                 else
00190                     go(B);
00191                 
00192                 // дай угадаю, не работает?
00193                 delay_ms(2500);
00194                 delay_ms(2500);
00195                 
00196                 this_move = B;
00197             }
00198         }
00199     }
00200     
00201     // этот цикл организует движение на свет, пока
00202     // есть сигнал хотя бы от одного из датчиков освещенности
00203     while ( (bit_is_clear(PININ, LIGHT_R)) || (bit_is_clear(PININ, LIGHT_L)) ) {
00204         if ( (bit_is_clear(PININ, LIGHT_R)) && (bit_is_clear(PININ, LIGHT_L)) )
00205             go(F);
00206         else { //<- без этих скобок потенциальное место ошибок
00207             if (bit_is_clear(PININ, LIGHT_R))
00208                 go(FR);
00209             else
00210                 if (bit_is_clear(PININ, LIGHT_L))
00211                     go(FL);
00212         }
00213     }
00214 }
00215 
00219 int main(void)
00220 {
00221     DDROUT  = 0xff;
00222     PORTOUT = 0x00;
00223 
00224     DDRIN   = 0x00;
00225     PORTIN  = 0xff;
00226 
00227     // запускаем главный цикл
00228     while(true)
00229         walk();
00230 
00231     return 0;
00232 }

Документация по robot. Последние изменения: Fri Apr 18 11:24:41 2008. Создано системой  doxygen 1.5.3