roboforum.ru

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

как измерить длину импульсов?

как измерить длину импульсов?

ximik » 09 янв 2011, 18:10

Есть 2х канальная радиоаппаратура, на выходе приемника импульсы для управления сервами или регуляторами скорости.
Задача стоит в том чтобы измерить длину управляющих импульсов и интерпретировать сигналы "газ" "поворот" в сигналы для танкового привода.

Вот кусок кода для ATmega8 (кварц 16МГц)
Прерывания настроены на любое изменение состояния порта
подтягивающие резисторы на порт D включены
Код: Выделить всёРазвернуть
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
if (flag1==0) {TCNT0=0x00;
               flag1=1;
              }
else  {flag1=0;
       move1=TCNT0;   
      };

 
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
if (flag2==0) {TCNT0=0x00;
               flag2=1;
              }
else  {flag2=0;
       move2=TCNT0;   
      };

переменный move1 и move2 хранят длину импульсов с 2х каналов.
НО!
Программа работает но считается только длина импульса на ноге "INT0".
Считает и импульс на ноге "INT1", если отключить прерывание на INT0 и оставить только INT1.
То-есть можно сделать вывод, что импульсы начинаются одновременно.

Если пытаться "поймать" импульс в основном цыкле программы, отключив внешние прерывания
Код: Выделить всёРазвернуть
 while(flag1==0){ if(PORTD.2==1){TCNT0=0;
                                        flag1=1;
                                       };
                       }; 
                     
         while(flag1==1){ if(PORTD.2==0){move1=TCNT0;
                                        flag1=0;
                                       };
                       };               


то ничего не получается вообще(
Вот и хочу спросить каким образом можно реализовать поставленную выше задачу на ATmega8?

Re: как измерить длину импульсов?

avr123.nm.ru » 09 янв 2011, 19:04

Если у вас 2 сигнала то используйте 2 ноги внешних прерываний но настраивайте прерывание каждый раз на то событие которое ожидаете.

Re: как измерить длину импульсов?

Radist » 09 янв 2011, 20:13

Я на Сях не пишу, поэтому мой ответ будет скорее общим, чем частным. Внешние прерывания работают оба - это точно. Если они произойдут одновременно, то нулевое прерывание будет обработано первым. Но флаг срабатывания первого прерывания сбрасывает только возврат из подпрограммы прерываний. Так что даже в этом случае прерывания должны обработаться оба. В симуляторе пробовали имитировать?

Re: как измерить длину импульсов?

Duhas » 09 янв 2011, 22:30

фронт смотреть одним прерыванием, спады - двумя.. по фронту пускать таймер, и переключать режимы прерываний, по спаду - смотреть таймер и возвращать режимы

Re: как измерить длину импульсов?

ximik » 10 янв 2011, 14:26

Все разобрался, заработало.
В протеусе пробовал но он вообще на прерывания не реагирует(может версия карявая...)
На счет того что должны работать влюбом случае оба - да, но импульс тогда измерится не правильно.
сделал вот так
Код: Выделить всёРазвернуть
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
if (flag1==0) {TCNT0=0x00;
               flag1=1;
              }
else  {flag1=0;
       move1=TCNT0;
       GICR=0x80;
      };

 
}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
if (flag2==0) {TCNT0=0x00;
               flag2=1;
              }
else  {flag2=0;
       move2=TCNT0;
       GICR=0x40;
      };

}

то-есть внутри первого прерывания отключаем разрешение на его срабатывание, а во втором после выполнения разрешаем, в итоге они поочереди выполняются несмотря на одновременное начало импульсов


cron
Rambler\'s Top100 Mail.ru counter