roboforum.ru

Технический форум по робототехнике.

Куплю программу!

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Куплю программу!

Сообщение gambit6 » 19 окт 2005, 17:22

Помогите, нужна программа, точнее всего часть программы уже написана, нужна часть, для датчиков расстояния.
Прога взята с сайта робоклуба, написана на 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();

}
Аватара пользователя
gambit6
 
Сообщения: 189
Зарегистрирован: 10 янв 2005, 12:18
Откуда: Санкт-Петербург

Сообщение chief » 19 окт 2005, 22:56

На счет программы я тебе не помогу так как пишу на асме, но с освобождением прерываний пожалуйста. Так как сигналы дискретные, их можно завести на регистр(ы) и одновременно на сумматор. Выход сумматора на одно из прерываний. Таким образом при появлении сигнала от датчика он через суматор прийдет на вход внешнего прервывания а контроллер сможет защелкнуть регистр и считать его, узнав тем самым какой датчик сработал.
Удачи...
http://www.avrdevices.narod.ru ICQ 204203081 Жду ваших предложений...
Аватара пользователя
chief
 
Сообщения: 60
Зарегистрирован: 22 янв 2005, 21:47
Откуда: Нетешин Хмельницкая обл. Украина


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron