реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Тахометр на 16меге, не могу разобраться
GDI
сообщение May 28 2007, 07:18
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Если хватит диапазона то сделать так:
Код
g = Speed_p * 166;

, а при индикации тупо ставить запятую где надо. Если диапазона int не хватит , то объявить переменную как long int g. Т.е. если у вас и входная и выходная переменные целочисленные, то не к чему делать вычисления с плавающей точкой - все равно потеряете точность и как следствие получите дополнительную погрешность при преобразовании типов.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 28 2007, 07:22
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Цитата(GDI @ May 28 2007, 11:18) *
Если хватит диапазона то сделать так:
Код
g = Speed_p * 166;

, а при индикации тупо ставить запятую где надо. Если диапазона int не хватит , то объявить переменную как long int g. Т.е. если у вас и входная и выходная переменные целочисленные, то не к чему делать вычисления с плавающей точкой - все равно потеряете точность и как следствие получите дополнительную погрешность при преобразовании типов.

Я вывожу на индикатор целое число. И потом даже при увеличении погрешности если переменная Speed_p не изменяется, то и после умножения на константу любого типа выражение не должно прыгать.... По моему так..
Вообще у меня подозрения что как раз в момент когда выполняется
Код
Speed_p=TCNT0;
... и тут приходит импульс на вход тактирования таймера
        TCNT0=0;

а я его обнуляю.... возможно здесья теряю единицу.... Может это можно какнибудь отловить....

Сообщение отредактировал DAndy_boy - May 28 2007, 07:27
Go to the top of the page
 
+Quote Post
GDI
сообщение May 28 2007, 07:31
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



При умножении константы на константу, конечно результат будет один, вот только Speed_p скорее всего прыгает пусть даже и на единицу, которая и вырастает при умножении и преобразовании типов.
Попробуйте просто вывести на индикатор переменную Speed_p и посмотрите - как она меняется при работе.

Цитата
Speed_p=TCNT0;

Это у вас происходит внутри прерывания и все прерывания в данный момент запрещены до выхода из прерывания, т.е. если придет импульс на счетный вход, то сперва завершиться это прерывание, т.е. обнулится TCNT0, затем выполнится одна команда из основного цикла, а затем произойдет вход в новое прерывание.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 28 2007, 07:50
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Цитата(GDI @ May 28 2007, 11:31) *
...Это у вас происходит внутри прерывания и все прерывания в данный момент запрещены до выхода из прерывания, т.е. если придет импульс на счетный вход, то сперва завершиться это прерывание, т.е. обнулится TCNT0, затем выполнится одна команда из основного цикла, а затем произойдет вход в новое прерывание.

ну так ведь TCNT0 считает не зависимо от прерывания
Go to the top of the page
 
+Quote Post
ReAl
сообщение May 28 2007, 07:50
Сообщение #20


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(DAndy_boy @ May 28 2007, 10:22) *
Вообще у меня подозрения что как раз в момент когда выполняется
Код
Speed_p=TCNT0;
... и тут приходит импульс на вход тактирования таймера
        TCNT0=0;

а я его обнуляю.... возможно здесья теряю единицу.... Может это можно какнибудь отловить....

Да, тут запросто можно потерять. Причём как не старайся - свести вероятность потери к нулю при таком подходе (с обнулением) не выйдет. Нужно дать счётчику бежать свободно и брать разницу двух последовательных показаний за интервал. При этом всё равно в соседние секундные интервалы будут разные значения - при "нецелом" числе импульсов в секунду (скажем, не 100Гц, а 99.5) гарантированно будет, что соседние секундные интервалы содержат разное число импульсов - то 99, то 100. Для 99.9Гц в девяти секундных интервалах будет 100 импульсов, а в одном - 99.
Но при свободно бегущем счётчике и взятии разности показаний ни один импульс не будет потерян вообще - он добавится к следующему результату и после фильтрации будет правильная и "твёрдо стоящая" величина.

p.s. При таких низких частотах я тоже рекомендую измерение периода и пересчёт.
INPUT CAPTURE поможет хватать содержимое счётчика. Чтобы не заморачиваться с ловлей количества переполнений таймера между двумя захватами - выберите предделитель так, чтобы на самой низкой частоте период переполнения таймера был заведомо больше, чем период входного сигнала. Тогда можно брать просто разность двух захватов в ICR и всё.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
muravei
сообщение May 28 2007, 17:11
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 2 538
Регистрация: 13-08-05
Пользователь №: 7 591



Цитата(DAndy_boy @ May 28 2007, 11:13) *
Т.е. надо завести входной сигнал на внешнее прерывание и по фронту запускать счетчик... а по другому его останавливать... и затем секунду делим на получившееся время... Так?

На вход захвата .
Можно умножить на период считаемой таймером частоты.
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 29 2007, 04:40
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Я все понял... вечером буду пробовать.... о результатах сообщу... Спасибо всем.
Go to the top of the page
 
+Quote Post
Диm
сообщение May 29 2007, 06:33
Сообщение #23


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 31-05-06
Пользователь №: 17 614



Цитата(muravei @ May 28 2007, 13:02) *
А может лучше мерять период вх сигнала , а не частоту? А после на "скользящее среднее"

я так сделал один разsmile.gif работает на ура! а измерять за секунду число имульсов удобно когда их большое число(скажем на валу стоит диск в котором насверлено 1024 дырки тогда получится оч. хорошая разрешающая способность)
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 29 2007, 10:26
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Начал разбираться с режимом захвата.... и все никак не получается в AVRStudio выставляю флаг на выходе компаратора, а захвата на таймере не происходит.... или это исключительно в симуляции... или я чего не правильно делаю... Может у кого есть какой пример... или скажите где я ошибаюсь, пожалуйста
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>

int zahvat;

SIGNAL (ANA_COMP_vect)
{

}

SIGNAL (TIMER1_CAPT_vect)
{

zahvat=1;

}

int main()
{// Declare your local variables here
/// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7372,800 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: On
// Input Capture on Rising Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0xC1;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

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

// Analog Comparator initialization
// Analog Comparator: On
// The Analog Comparator's positive input is
// connected to the Bandgap Voltage Reference
// Analog Comparator Input Capture by Timer/Counter 1: On
ACSR=0x44;
SFIOR=0x00;

// Global enable interrupts
sei();
while(1)
{
if(zahvat==1)//произошол захват
{
// подсчитываем период
...
zahvat=0;
}
}

}
Go to the top of the page
 
+Quote Post
aesok
сообщение May 29 2007, 10:33
Сообщение #25


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Есть такое волшебное слово: volatile. avr-libc-user-manual FAQ#1, или поиск на форуме.

Анатолий.
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 29 2007, 10:52
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Цитата(aesok @ May 29 2007, 14:33) *
Есть такое волшебное слово: volatile. avr-libc-user-manual FAQ#1, или поиск на форуме.

Анатолий.

Я знаю и про первое (хотя и вопрос не в этом) и выполнил второе.... и только потом задал данный вопрос....
Go to the top of the page
 
+Quote Post
aesok
сообщение May 29 2007, 11:12
Сообщение #27


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(DAndy_boy @ May 29 2007, 14:52) *
Я знаю и про первое (хотя и вопрос не в этом) и выполнил второе.... и только потом задал данный вопрос....


а почему тогда - int zahvat; - ???

Объясните поодробнее слова "а захвата на таймере не происходит", как вы это определяете.

В хелпе на AVRStudio описано какая перефирия не симулируется, уточните там начет компоратора.

Анатолий.
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение May 29 2007, 11:21
Сообщение #28


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Цитата(aesok @ May 29 2007, 15:12) *
а почему тогда - int zahvat; - ???

Это только для примера...
Цитата(aesok @ May 29 2007, 15:12) *
В хелпе на AVRStudio описано какая перефирия не симулируется, уточните там начет компоратора.

Это вы про это?
"Analog Comparator (AC)
Analog Comparator is not supported."
Только сейчас увидел.... даже и не думал.... что такие ограничения.....не ужели не прокатит код

Цитата(aesok @ May 29 2007, 15:12) *
Объясните поодробнее слова "а захвата на таймере не происходит", как вы это определяете.


ну как как? в симуляторе смотрю что регистр захвата не обновляется .... как был 0x0 так и остается... при любом изменениии(естественно мною) регистра ACO

Сообщение отредактировал DAndy_boy - May 29 2007, 11:26
Go to the top of the page
 
+Quote Post
muravei
сообщение May 29 2007, 13:24
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 538
Регистрация: 13-08-05
Пользователь №: 7 591



Цитата(aesok @ May 29 2007, 15:12) *
В хелпе на AVRStudio описано какая перефирия не симулируется, уточните там начет компоратора.

А в Алгоритм Билдере симулируется, и еще можно на вход импульсы подать...
Go to the top of the page
 
+Quote Post
DAndy_boy
сообщение Jun 1 2007, 04:43
Сообщение #30


Местный
***

Группа: Свой
Сообщений: 211
Регистрация: 25-09-05
Из: Москва
Пользователь №: 8 922



Господа, опять прошу помощи…. Почитав описание компаратора и режим захвата таймера я пришел к выводу, что при использовании внутреннего опорного напряжения захват будет идти только по срезу входного сигнала… Что не очень удобно, по крайне мере в моем случае. По этому пришлось использовать внешнее опорное напряжение и поменять местами входы компаратора, т.е. на не инвертирующий вход подавать измеряемый сигнал, а на другой - внешнее опорное напряжение? поскольку входной сигнал имеет форму пилы (от 0 до 100 Гц). И все-таки в процессе работы появились подозрения, что бывают моменты, когда захват происходит как по срезу, так и по фронту. И в результате никак не могу получить стабильные результаты, значения прыгают на 1,2 герца. Или тут не обойтись без усреднения за несколько интервалов? Прилагаю код, может кто увидит косяк…

Код
#define QZ              7372800L
#define    TIME_OCR1A      ((QZ / 1024))
        
volatile long Zahvat1=0;// захват первого фронта
volatile long Zahvat2=0;// захват первого фронта
volatile long TOVER=0;// то количество импульсов которое насчитали до
                                  //сброса таймера на секунде и до прихода фронта измеряемого сигнала
long Zah_end;// количество тактов Таймера между фронтами
volatile int k=0; // указывает на каком этапе находимся


SIGNAL (TIMER1_CAPT_vect)
{
    // здесь происходит захват значения таймера
if(k==0)
{// захватываем первый фронт
   Zahvat1=ICR1+TOVER;
   TOVER=0;
   k=1;
}
else if(k==1)
  {// захватываем второй фронт
    Zahvat2=ICR1+TOVER;
    TOVER=0;
  //данные готовы    для преобразования и вывода
   k=5;
   }
}


SIGNAL (TIMER1_COMPA_vect)
{
// прерывание каждую секунду
// поскольку значение таймера сбрасывается, то сохраняем количество импульсов которые насчитали
if(k!=5 && TOVER!=0){Zahvat1=Zahvat2=0;k=0;}
  if(k==0)
    {TOVER+=TIME_OCR1A-Zahvat1;Zahvat1=0;}
    else
  if(k==1)
   { TOVER+=TIME_OCR1A-Zahvat2;Zahvat2=0;}
   else
   if(k==5)TOVER=0;
    
}


/****************************************************************************
                      Timer1_init()
  Функция инициализации Timer1.
****************************************************************************/                    
void Timer1_init(void)
{
    OCR1A = TIME_OCR1A;        /* прерывание раз в секунду */
                TCCR1A = 0x00;
                TCCR1B = (1 << 3) | 0x05;
                TIMSK |=  1 << 4;  /* разрешить прерывание OCIE1A */
                TIMSK |=1<<5; // режим захвата
}



int main()
{
int g;
Timer1_init();

PORTC=0x00;
DDRC=0xFF;

// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=0 State6=0 State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0xC0;


DDRA|=(1<<4);

// Port B initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In
// State7=0 State6=0 State5=T State4=T State3=0 State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;


// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=T State2=T State1=0 State0=0
PORTD=0x0C;
DDRD=0xF3;

// Analog Comparator initialization
// Analog Comparator: On
// Analog Comparator Input Capture by Timer/Counter 1: On
ACSR=0x04;
SFIOR=0x00;

sei();

do
{
  if(k==5)
   {// значения готовы
       if(Zahvat2>Zahvat1)
       { // значения верны
                       str_out[0]=0; // выводим флаг ошибки (все удачно)
             Zah_end=(Zahvat2-Zahvat1);
                       g=(TIME_OCR1A)/Zah_end; // вычисляем период
           TOVER=0;
    
           str_out[5]=g%10;g/=10;
             str_out[4]=g%10;g/=10;
           str_out[3]=g%10;g/=10;
           str_out[2]=g%10;g/=10;  
      }
                else
                 // значения не верны след. не учитываем их     
                   str_out[0]=1; // выводим флаг ошибки
           k=0;
   }

   reload(); // динамическая индикация
}while(1);

}
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 17:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01546 секунд с 7
ELECTRONIX ©2004-2016