Помогите, нужна программа, точнее всего часть программы уже написана, нужна часть, для датчиков расстояния. Прога взята с сайта робоклуба, написана на AVREdit3.5 (Я переписал ходовую часть программы под гусеничный вариант.) Но в ней датчики заведены на внешние прерывания, хотелось бы освободить линии прерывания и подключить 2 датчика gp2d120, один спереди, другой сзади. Эти датчки должны срабатывать на расстоянии 10-15 см до препятствия. Кто может помочь, ниже выкладываю код программы. Я понимаю, что мало кто захочет помочь мне бесплатно, так что могу оплатить 3WMZ за работу. Помогите, плиз. В проге нужно просто заменить прерывания на код для датчиков gp2d120. К сожалению я не имею ни малейшего представления о том как это сделать. Говорят можно как-то через АЦП.... Кварц у меня на 4 mhZ //------------------------------------------------------------------------
#include <inttypes.h> #include <io.h> #include <sig-avr.h> #include <interrupt.h> #include <stdlib.h>
// назначение определений для удобства работы с периферией #define OUT PORTB #define MOTOR1_F PB7 // Это я переделывал #define MOTOR1_B PB6 #define MOTOR2_F PB5 #define MOTOR2_B PB4
#define IN PIND #define LIGHT_R PD0 #define LIGHT_L PD1 #define BUMPER_F PD2 #define BUMPER_B PD3
// Возможные режимы движения enum {STOP, F, FR, FL, B, BR, BL};
//------------------------------------------------------------------------------ // Задержка t х 10ms //------------------------------------------------------------------------------ #define F_CPU 4000000 #define K_DELAY_10ms F_CPU/600 void Delay_10ms(unsigned char t) { unsigned int i; if (t==0) return; while (t--) for(i=0;i<K_DELAY_10ms; i++); }
// таблица вероятностей для выбора направления движения // исходя из текущего направления движения unsigned char p[7][7] = { {14, 86, 57, 71, 43, 93, 100}, {7, 100, 71, 100, 43, 100, 100}, {7, 100, 93, 100, 50, 100, 100}, {7, 100, 57, 100, 50, 100, 100}, {29, 57, 29, 29, 29, 79, 100}, {36, 71, 36, 36, 36, 93, 100}, {36, 71, 36, 36, 36, 79, 100}, };
// текущее направление движения unsigned char this_move;
//------------------------------------------------------------------------------ // Включение комбинации моторов для движения в заданном направлении //------------------------------------------------------------------------------ void go(unsigned char direction){
switch (direction) { case STOP: cbi(OUT, MOTOR1_F); cbi(OUT, MOTOR1_B); cbi(OUT, MOTOR2_F); cbi(OUT, MOTOR2_B); break;
case F: sbi(OUT, MOTOR1_F); cbi(OUT, MOTOR1_B); sbi(OUT, MOTOR2_F); cbi(OUT, MOTOR2_B); break;
case FR: cbi(OUT, MOTOR1_F); cbi(OUT, MOTOR1_B); sbi(OUT, MOTOR2_F); cbi(OUT, MOTOR2_B); break;
case FL: sbi(OUT, MOTOR1_F); cbi(OUT, MOTOR1_B); cbi(OUT, MOTOR2_F); cbi(OUT, MOTOR2_B); break;
case B: cbi(OUT, MOTOR1_F); sbi(OUT, MOTOR1_B); cbi(OUT, MOTOR2_F); sbi(OUT, MOTOR2_B); break;
case BR: cbi(OUT, MOTOR1_F); cbi(OUT, MOTOR1_B); cbi(OUT, MOTOR2_F); sbi(OUT, MOTOR2_B); break;
case BL: cbi(OUT, MOTOR1_F); sbi(OUT, MOTOR1_B); cbi(OUT, MOTOR2_F); cbi(OUT, MOTOR2_B); break; } }
//------------------------------------------------------------------------------ // Выбор направления движения в следующем шаге по таблице вероятностей //------------------------------------------------------------------------------ unsigned char next_move(void){ unsigned char pp, i;
pp = rand()/327; // получаем случайное число 0..99 for (i=0;i<7;i++){ // ищем соответствие в таблице вероятностей if (p[this_move][i] > pp) break; } this_move = i; // записываем новое полученное направление как текущее return(i); }
//------------------------------------------------------------------------------ // Обработка прерывания от переднего бампера (INT0 = PD2) //------------------------------------------------------------------------------ SIGNAL(SIG_INTERRUPT0) { if(this_move==FR) go(BL); if(this_move==FL) go(BR); else go(B); Delay_10ms(250); // отъезд в течение 2.5 х 2 сек Delay_10ms(250); this_move=B; }
//------------------------------------------------------------------------------ // Обработка прерывания от заднего бампера (INT1 = PD3) //------------------------------------------------------------------------------ SIGNAL(SIG_INTERRUPT1) { if(this_move==BR) go(FL); if(this_move==BL) go(FR); else go(F); Delay_10ms(250); // отъезд в течение 2.5 х 2 сек Delay_10ms(250); this_move=F; }
//------------------------------------------------------------------------------ // "Случайное блуждание" //------------------------------------------------------------------------------ unsigned char walk(void){ // этот цикл организует "свободное блуждание" пока // нет сигнала ни от одного из датчиков освещенности while((bit_is_set(IN, LIGHT_R)) && (bit_is_set(IN, LIGHT_L))){ go(next_move()); // получаем следующее направление движения и Delay_10ms(250); // движемся в этом направлении 2.5 сек } // этот цикл организует движение на свет, пока // есть сигнал хотя бы от одного из датчиков освещенности while((bit_is_clear(IN, LIGHT_R)) || (bit_is_clear(IN, LIGHT_L))){ if((bit_is_clear(IN, LIGHT_R)) && (bit_is_clear(IN, LIGHT_L))) go(F); else if(bit_is_clear(IN, LIGHT_R)) go(FR); else if(bit_is_clear(IN, LIGHT_L)) go(FL); }
return(0); }
//------------------------------------------------------------------------------ // Главная программа //------------------------------------------------------------------------------ int main(void) { DDRB = 0xff; // назначаем все линии порта B на выход PORTB = 0x00; // и устанавливаем на них низкий уровень
DDRD = 0x00; // назначаем все линии порта D на вход PORTD = 0xff; // подключаем внутренние нагрузочные резисторы
// разрешаем прерывания int0 и int1 outb(GIMSK, (1<<INT0)|(1<<INT1));
// запрос на прерывание - по спадающим фронтам на int0 и int1 outb(MCUCR, (1<<ISC01)|(1<<ISC11));
// разрешаем прерывания sei();
// запускаем главный цикл while(1) walk();
}
|