как подсчитать длительность импульса в CVAVR на ATMega8

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

как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение gunner05 » 29 фев 2008, 19:12

вынесено из
http://www.roboforum.ru/viewtopic.php?f=2&t=3295&st=0&sk=t&sd=a&start=15

с чего началось
пытаюсь собрать платформу (машинку) на радиоуправлении с четырьмя моторами, кодер и декодер собрал
декодер выдает (проверено осциллографом) импульсы от 1 до 2мс в зависимости от положения рычажка джойстика ..
также собрал Н-мосты на полевиках, на мосте есть выход А (крутить в лево) и Б (вправо) ...
над приемником и передатчиком сейчас работаю ...

теперь вопросы:

1. для управления н-мостами нужен контроллер (на меге8 желательно) ... нужно чтобы этот контроллер считывал ДЛИТЕЛЬНОСТЬ ИМПУЛЬСА с декодера и реагировал след. образом

1мс - полный назад или вперед
.
. изменение скорости
.
1,5мс - стоп
.
. изминение скорости
.
2мс - полный назад или вперед

как регулировать ШИМ вроде понятно ... а вот как считывать длительность импульсов ... нет
вот ...


облазив весь google, конкретных примеров не нашел, но вроде разобрался сам ....

частота МК 8 MHz

Код: Выделить всё
#include <mega8.h>
#include <stdio.h>

void main(void)
{

PORTC=0x00;
DDRC=0x02;  // на С0 подаем импульс а с С1 читаем

TCCR0=0x00;  // счетчик T0 остановлен
TCNT0=0x00;

//USART
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

while (1)
      {
      if (PINC.0) {
            TCCR0=0x04; //запускаем счетчик с пределителем 256
              while (PINC.0) {            //пустой цикл пока на ноге С0 еденица
               }
      }

TCCR0=0x00; //останавливаем счетчик

if (TCNT0>0) {
printf("T0 = %d\r\n", TCNT0); //выводим на терминал T0
}
TCNT0=0x00; //обнуляем счетчик
};
}


получается
при 1мс TCNT = 31
при 2мс TCNT= 62

проверяем 31 * 256 *0,125мкс = 992 мкс или ~1мс
62 * 256 * 0,125 = 1984 мкс или ~2 мс
:)

Добавлено спустя 10 минут 4 секунды:
вот тоже самое только используя внешнее прерывание INT0 :)

Код: Выделить всё

#include <mega8.h>
// Standard Input/Output functions
#include <stdio.h>

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
   if (PIND.2) {
        PORTC.1=1;
        TCCR0=0x04;
                while (PIND.2) {
                }
        }
   PORTC.1=0;
   TCCR0=0x00;
   if (TCNT0>0) {
   printf("T0 = %d\r\n", TCNT0);
   TCNT0=0x00;       
   }
}

void main(void)
{

PORTB=0x00;
DDRB=0x00;

PORTC=0x00;
DDRC=0x02;

PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
GICR|=0x40;
MCUCR=0x03;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;


// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here

      };
}


эмуляция делалась в протеусе 7.2 SP2 , попробовал на другом компе в версии 7.1 SP2 , запустилась, но работает не корректно.
Вложения
reading_PWM 1-2ms.rar
весь проэкт и эмуляция в Протеусе
(140.85 КиБ) Скачиваний: 76
Аватара пользователя
gunner05
 
Сообщения: 18
Зарегистрирован: 31 окт 2007, 00:19
Откуда: Украина, Донецк

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение RoboTok » 03 мар 2008, 13:00

Я абсолютно тем же мучил на 3 форумах людей.

Короче сделал это и понял, что зря парился.

Можешь поискать мои программы для МК на форуме, там я подробно всё описывал.
Или на форуме roboclub.ru посмотреть ник Gromogon.

Кратко как я делал.
Настраивал прерывание на ноге МК.
Задавал частоту таймера в 8 раз быстрее чем самый короткий импульс.
При прерывании на ноге по лог 0 включал счёт таймера.
При лог 1 останавливал и обрабатывал.
Аватара пользователя
RoboTok
 
Сообщения: 1060
Зарегистрирован: 04 фев 2008, 13:18
Откуда: Москва
прог. языки: PHP

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение gunner05 » 04 мар 2008, 12:53

RoboTok писал(а):Короче сделал это и понял, что зря парился.

почему?

RoboTok писал(а):Кратко как я делал.
Настраивал прерывание на ноге МК.
Задавал частоту таймера в 8 раз быстрее чем самый короткий импульс.
При прерывании на ноге по лог 0 включал счёт таймера.
При лог 1 останавливал и обрабатывал.


у меня тоже самое тока по лог 1 включается а по 0 выключается.
Аватара пользователя
gunner05
 
Сообщения: 18
Зарегистрирован: 31 окт 2007, 00:19
Откуда: Украина, Донецк

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение RoboTok » 04 мар 2008, 22:36

Мне нужно было ДУ передавать пакет данных, а сделать смог только обработку длительности импульсов.
Ктому же ДУ ИК не подходит для управления моей машинкой, т.к. нужна стабильная связь в двух направлениях.
Если вы делаете радио пульт, то может будет смысл какой то, но нормальной пакетной связи у вас всё равно не выйдет.
Аватара пользователя
RoboTok
 
Сообщения: 1060
Зарегистрирован: 04 фев 2008, 13:18
Откуда: Москва
прог. языки: PHP

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение gunner05 » 05 мар 2008, 11:17

RoboTok писал(а):Ктому же ДУ ИК не подходит для управления моей машинкой, т.к. нужна стабильная связь в двух направлениях.

ну тут вы наверное не до конца все изучили, на сколько я знаю, продаются комнатные вертолеты, которые так же управляются с помощью ИК ... я думаю им нужна гораздо более уверенная связь чем машинке :wink:
RoboTok писал(а):Если вы делаете радио пульт, то может будет смысл какой то

делаю радио пульт.
RoboTok писал(а):но нормальной пакетной связи у вас всё равно не выйдет.

тут вы ошибаетесь, уже вышло, кодер и декодер работает ... пакеты формируются и декодируются ... можно посылать до 9 команд одновременно :).
покупная радиоаппаратура тоже после декодирования пакета импульсов на каждый канал дает импульсы 1-2мс, так что можно и ее использовать, именно поэтому я ориентируюсь на такую длительность, если не получится самодельная, можно применить покупную, а контроллер подойдет :)
Аватара пользователя
gunner05
 
Сообщения: 18
Зарегистрирован: 31 окт 2007, 00:19
Откуда: Украина, Донецк

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение Myp » 05 мар 2008, 14:15

комнатные вертолёты с ИК ничем кардинально не отличаются от пульта от телека

просто там стоит пачка ИК диодов которая светит так сильно что вертолёт в любой точке комнаты принимает сигнал

короче как люстра в комнате
если включить то даже под кроватью светло
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение RoboTok » 06 мар 2008, 11:22

gunner05 писал(а):тут вы ошибаетесь, уже вышло, кодер и декодер работает

Я ж написал нормальной пакетной связи, а не кодер-декодер.
Ктому же мне нужна двух сторонняя связь и за прямой видимостью.
Конечно, можно поставить мощные ИК диоды и может и в другую комнату сможет пробить с закрытой дверкой, но уже извращение.

А я хочу поставить самодельный или покупной трансивер, с которым можно по SPI работать как с модемом.
И он сам всё делает и только выдаёт уже полученные данные.
Я просто прикинул, если я буду сам всё делать и софт писать для кодера-декодера и т.д., то мой проект останется не завершённым.
А ради завершения я готов даже купить готовые блоки 8)

Добавлено спустя 2 минуты 31 секунду:
Myp писал(а):короче как люстра в комнате


Я тоже мощность повысил ИК диода, в импульсном режиме от потянул 100мА, и приём со всех углов стал нормальный :crazy:
Аватара пользователя
RoboTok
 
Сообщения: 1060
Зарегистрирован: 04 фев 2008, 13:18
Откуда: Москва
прог. языки: PHP

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение Myp » 06 мар 2008, 11:42

у меня дома пачка 100 мА суперярких ИК светиков лежит
дык вот если несколько штук запаралелить то можно видеокамерой ночное видео снимать

а вертолёт запросто летает и за углом в соседней комнате
тока недолго
потому что его не видно и в конце концов он куданить врезается :P


у одного японца была собрана полусфера из неск десятков :shock: ИК диодов мощных
он ею управлял моделью самолёта

вобще достаточно светить в потолок ИК светиками и тсоп на роботе направить тоже в потолок
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение LOM » 11 июн 2008, 02:16

to gunner05 спасибо! мне эти примры очень помогли! :Yahoo!:
А может кто нибудь выложить пример в том же стиле в cvavr для работы с 16битным счетчиком? :roll:

Спасибо :beer:
LOM
 
Сообщения: 3
Зарегистрирован: 11 июн 2008, 02:05

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение LOM » 14 июн 2008, 01:38

Спасибо за дружественное молчание :lol: Хорошо хоть сразу не послали сами знаем куда (avr123.nm.ru)

Вроде разобрался вот пример
Код: Выделить всё
#include <mega16.h>
#include <stdio.h>

int Cur=0,Prev=0,k=0;//Целочисленные переменные размером по 16бит Cur-текущее значение счетчика Prev-предидущее значение счетчика

interrupt [EXT_INT0] void ext_int0_isr(void)  // Прерывание по изменению уровня на ноге D2(INT0)
{
        if(PIND.2==1)//Если прерывание сработало по положительному фронту(переход с 0 в 1)
        { 
                Cur=TCNT1; //Записываем в переменную Cur значение счетчика
                TCNT1=0x00;
                TCCR1A=0x00;
                TCCR1B=0x05;//Запускаем счетчик с предделителем частоты 1024(8Мгц/1024=7812,5Гц)
                k++;
                if(k>4)
                k=1;
        }
}

void init(void)
{

GICR|=0x40;
MCUCR=0x01;
MCUCSR=0x00;
GIFR=0x40;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;

TIMSK=0x00;

UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x67;

ACSR=0x80;
SFIOR=0x00;



#asm("sei")
}


void main(void)
{
float Time=0;
int RPM=0,Prev1=0,Prev2=0,Prev3=0,Prev4=0;


init();


while (1)
      {
       if(k==1)
       Prev1=Cur;
       if(k==2)
       Prev2=Cur;
       if(k==3)
       Prev3=Cur;
       if(k==4)
       Prev4=Cur;
     
     
      Prev=(Prev1+Prev2+Prev3+Prev4)/4;
       Time=Prev*0.256;
       RPM=(1000/Time)*60;
       
       
        printf("RPM: %d\n",RPM);
        printf("Timer: %d\n",TCNT1);
      };
}

8Mhz...
Простой тахометр... не знаю будет ли работать, Протеус 7.1 не хочет работать с прерываниями(((
Если код не правильный то прошу поправить кто чем может...
LOM
 
Сообщения: 3
Зарегистрирован: 11 июн 2008, 02:05

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение avr123.nm.ru » 14 июн 2008, 08:29

Может лучше прерывание по положительному фронту использовать ?

RPM типа FLOAT будет

может так:
Код: Выделить всё
Time=((float)(Prev1+Prev2+Prev3+Prev4))*0.064 ; 
RPM=(60000.0/Time);


или так:
Код: Выделить всё
RPM = 937500.0/((float)(Prev1+Prev2+Prev3+Prev4));
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение blindman » 14 июн 2008, 08:49

Самый простой и точный способ мерять период импульса - использовать вход захвата (ICP1)
Проект [[Open Robotics]] - универсальные модули для построения роботов
Модули Open Robotics можно приобрести в магазине shop.roboforum.ru

Day OFF? You must be pulling my leg! Stop making humor before someone sees you, fool!

Аватара пользователя
blindman
 
Сообщения: 4130
Зарегистрирован: 29 апр 2008, 21:15
Откуда: Хабаровск
прог. языки: C,C++,Assembler,PHP,Javascript,Ruby, SPIN,Java(?)
ФИО: Андрей Юрьевич

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение LOM » 18 июн 2008, 01:50

avr123.nm.ru
Если RPM ,будет Float то будет затруднена читабельность показаний т.к очень быстро будет изменяться значение после запятой :sorry:

blindman
А пример не приведете с захватом вместо прерывания?
LOM
 
Сообщения: 3
Зарегистрирован: 11 июн 2008, 02:05

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение blindman » 18 июн 2008, 04:37

Не вместо, а вместе.

Какой пример нужен? Код не напишу, лениво лезть в даташит, смотреть в какой регистр что писать. На словах расскажу. Таймер считает от 0 до 0xFFFF, вход ICP1 настраивается на захват по фронту/спаду. В прерывании по захвату, используешь значение ICR1 вместо TCNT1, значение TCNT1 не меняешь. Так как значение счетчика и ICR1 меняется только аппаратно, получаем бОльшую точность.
Проект [[Open Robotics]] - универсальные модули для построения роботов
Модули Open Robotics можно приобрести в магазине shop.roboforum.ru

Day OFF? You must be pulling my leg! Stop making humor before someone sees you, fool!

Аватара пользователя
blindman
 
Сообщения: 4130
Зарегистрирован: 29 апр 2008, 21:15
Откуда: Хабаровск
прог. языки: C,C++,Assembler,PHP,Javascript,Ruby, SPIN,Java(?)
ФИО: Андрей Юрьевич

Re: как подсчитать длительность импульса в CVAVR на ATMega8

Сообщение avr123.nm.ru » 18 июн 2008, 08:29

LOM писал(а):avr123.nm.ru
Если RPM ,будет Float то будет затруднена читабельность показаний т.к очень быстро будет изменяться значение после запятой :sorry:


Вы можете сами решать в каком формате и как часто быдете выводить данные на индикатор.
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва


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

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

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