Перейти к содержанию
    

Частотомер на Atmega8 (CVAVR)

Если измерять частоты надо одновременно, то вот вам пара путей реализации.

 

1) Взять два МК, те же тайни, в них - одна и та же уже готовая программа с единственным отличием - один МК получает измеренную частоту из второго, скажем, по spi или уарт, не суть важно.

 

2) Взять один МК с двумя схемами захвата, программа будет посложнее, но тоже реализуема в обозримое время.

 

Какой вариант реализации выбрать - зависит от вашей лености.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но ведь вроде T0 и T1 асинхронные, и считают независимо от исполнения других комманд? Сейчас автогенератор работает в режиме перевозбуждения (что не есть гуд и приводит к нелинейности), вообще планируется выходной сигнал через прецезионный выпрямитель пустить на АЦП и таким образом завести ООС, чтобы датчик был с линейной характеристикой. Поскольку частоты не велики, нет ну правда, всего-то два сигнала 10кГц каждый, думается можно вполне все успевать.

 

2) Взять один МК с двумя схемами захвата, программа будет посложнее, но тоже реализуема в обозримое

Т.е. все таки без двух захватов не обойтись? А если программно отключать входы?

Мне сверх высокая точность не нужна, достаточно двух знаков после запятой, дальше все равно уже шумы, вибрации, и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, вот вам ещё вариант: берёте МК с тремя таймерами и одним захватом. Входные сигналы на таймер0 и таймер2, и их же подаёте через коммутатор на схему захвата. Дальше, думаю, не надо объяснять.

 

Вообще, для оценки частоты с двумя знаками после запятой, вам достаточно взять время измерения 10 мс. Предположим, что время интеграции вашей системы будет больше, т.е. вы измеряете постоянную величину. Исходя из этого, вот вам ещё вариант - измеряете частоты последовательно: F1, F2, F1, F2, F1,... Измерения затем можно статистически обработать. Стандартная девиация - очень важный параметр для оценки качества, не пренебрегайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

=GM= Заинтересовался Вашим способом, давно хотел сделать частотомер на работу, но как то не получалось..

Скомпоновал исходник из вашего поста 32 и поста 13 ps1x. Пробовал в протеусе и vmlab 315, показания пляшут. Из темы понял что это окончательный вариант алгоритма и все должно работать. Переменную Fx не выводил, смотрел в окне watch (я пока не знаю как вывести float, не используя fprint и т.п.).

Ну и вот тут у меня не понятки

TIMSK &=~_BV(TOIE1);                //запретим прерывания TOV1
  do
  {
   //
  }
  while((TIFR&_BV(TOV1))==0);         //ждём начала измерения
  ntick1=ICR1;   ntick2=nover;                      //запомним ICR1 и старшую часть
  if(TIFR &_BV(TOV1))//   <----------------?
  {
   nover++;
   TIFR =_BV(TOV1);                   //сбросим TOV1
   if(ntick1<0x8000) ntick2=nover;
  }

Зачем нужен if, ведь после while((TIFR&_BV(TOV1))==0); флаг TOV1 будет поднят, а прерывания запрещены? И к стыду не понял это if(ntick1<0x8000) ntick2=nover;

 

Прикрепил архив с проектом для протеуса и vmlab, алгоритм разбил на две функции, иначе в vmlab нельзя было поставить точки останова и увидеть N и M.

f.zip

Изменено пользователем horoc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, трудно обьяснить, попробую. Цикл do ... while((TIFR&_BV(TOV1))==0) достаточно длинный и может так случиться, что возник TOV1, сделана проверка и выход, хотя переменная nover не была должным образом модифицирована. Случается это редко, но случается, ps1x как раз с этим и столкнулся. Вот для этого такие навороты. Реализаций программы может быть множество, возможно именно эта - не самая лучшая.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я поэкспериментировал немного, сделал вот так.

void freg1(void){
    TCCR1B=(0<<ICES1)|(0<<CS10);//stop
    TCNT1=0;
    TIFR =(1<<TOV1);
    TIMSK &=~_BV(TOIE1);
    nover=0;
    mover=0;
    TCCR1B=(0<<ICES1)|(1<<CS10);//start
    TIFR=(1<<ICF1);
    while((TIFR&_BV(ICF1))==0);       
    if(TIFR &_BV(TOV1))               
        {                                
        nover++;                        
        TIFR =_BV(TOV1);                 
        }
    ntick2=nover;
    ntick1=ICR1;
    TIMSK |=_BV(TOIE1);
    mtick1=TCNT0;                   
    mtick2=mover;
    N1=((uint32_t)(ntick2)<<16)+(uint32_t) ntick1; //системные тики
    M1=((uint32_t)(mtick2)<<8) +(uint32_t) mtick1; //входные тики
}

void freg2(void){
    while(TCNT1<65525);
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    
    TIFR=(1<<ICF1);
    while((TIFR&_BV(ICF1))==0);
    ntick2=nover;
    ntick1=ICR1;
    mtick1=TCNT0;                    
    mtick2=mover;                
    N2=((uint32_t)(ntick2)<<16)+(uint32_t) ntick1;
    M2=((uint32_t)(mtick2)<<8) +(uint32_t) mtick1; 
    N=N2-N1;                           
    M=M2-M1;                      
    Fx=12000000.0*(float)M/(float)N;
}

Может коряво :laughing: но прыгать перестало, но особо не тестировал еще. Только вот сейчас смотрю, почему при входном 1Мег результат 999996.

Еще охота избавится от флоат, но не знаю как.

Изменено пользователем horoc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот еще на танцевал с бубном :yeah:

=GM= благодарю! :beer: я на такой результат и не рассчитывал. Для моих сугубо радиолюбительских целей лучше не надо.

 

--------------------------

немного изменил код

2.zip

Изменено пользователем horoc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую. Я плохо разбираюсь пока что в микроконтроллерах, но вот надо сделать частотомер, хотя там на самом деле толщиномер пойдет, но принцип на измерении частоты. Подскажите пожалуйста пойдет ли последняя схема при измерении частоты до 1 МГц и так же в какой форме там выходной сигнал (я так понял там какой то счетчик на выходе стоит) и как его вывести на LCD или что то подобное. Благодарю заранее.

Заранее извиняюсь что такие простые вопросы спрашиваю, просто разобраться надо быстро, в процессе буду изучать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пойдёт.

 

Выходной сигнал - двоичное число в оперативной памяти МК. Выводить можно 1001 способом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...