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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Частотомер на Atmega8 (CVAVR)
ps1x
сообщение Jun 9 2010, 17:23
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Делаю (пытаюсь сделать) частотомер по методу предложеному =GM= тут: http://electronix.ru/forum/index.php?showtopic=29796. Но вот что то не получается. Верней получается но не совсем. Во первых если я меняю задержку между началом и концом измерения то получаю существенно разные варианты. Но в то же время, если задержка ровно 1 сек (delay_ms(1000)wink.gif то результат выводится либо равный расчетному либо чуть больше. Причем как будто бы не хватает одного переполнения таймера 1 т.е. Perepol_Timer1++; и число N1 получается на 65536 меньше. Из за чего результат чуть больше. Но куда оно может пропасть?

код вообще то взят в основном отсюда http://pro-radio.ru/controllers/5978/(с комментариями) но там не работает регистрация поэтому спрашиваю тут.

Код
char gate;
static float Fx;
unsigned long int N, N0, M, M0, N1, M1;
unsigned int Perepol_Timer0=0, Perepol_Timer1=0, count_T1, count_T0,Perepol_Timer1_real;

//Прерывание по переполнению Timer/Counter 0
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
Perepol_Timer0++;//Увеличение переменной на 1
}

//Прерывание по переполнению Timer/Counter 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void){
if (gate){
        Perepol_Timer1++;//Увеличение переменной на 1
}
}

//Прерывание по захвату Timer/Counter 1
interrupt [TIM1_CAPT] void timer1_capt_isr(void){                  
count_T1=ICR1;//Значение регистра ICR1 переписывается в переменную
count_T0=TCNT0;//Значение регистра TCNT0 переписывается в переменную
TIMSK&=0xDF;//Запрет прерывания по захвату                          
if (TIFR&0b00000100==1){
Perepol_Timer1++;
TIFR&=0b00000100;
}
}


while (1){//Бесконечный цикл
#asm("cli")  
gate=0;
Perepol_Timer1=0;//Обнуление переменной
Perepol_Timer0=0;//Обнуление переменной
#asm("sei")//Разрешения прерываний
TIMSK|=0x20;//Разрешили захват
gate=1;
while ((TIFR&0x20)==0x20){}//Ожидание прерывания по захвату
Perepol_Timer1_real = Perepol_Timer1;
N0=(((unsigned long int)(Perepol_Timer1_real))<<16)+count_T1; //Расчет общего количества тиков системной частоты
M0=(((unsigned long int)(Perepol_Timer0))<<8)+count_T0;//Расчет общего количества тиков входной частоты
//sprintf(lcd_buffer, "PT1=%u;CT1=%u;PT0=%u;CT0=%u;\r", Perepol_Timer1_real, count_T1, Perepol_Timer0, count_T0);
//puts(lcd_buffer);
delay_ms(1000);//Задержка на 1 с
TIMSK|=0x20;//Разрешили захват
gate=0;
while ((TIFR&0x20)==0x20){}//Ожидание прерывания по захвату  
Perepol_Timer1_real = Perepol_Timer1;
N1=(((unsigned long int)(Perepol_Timer1_real))<<16)+count_T1; //Расчет общего количества тиков системной частоты
M1=(((unsigned long int)(Perepol_Timer0))<<8)+count_T0;//Расчет общего количества тиков входной частоты
sprintf(lcd_buffer, "PT1=%u;CT1=%u;PT0=%u;CT0=%u;\r", Perepol_Timer1_real, count_T1, Perepol_Timer0, count_T0);
puts(lcd_buffer);
N=(N1-N0);//Расчет количества тиков системной частоты за время измерения
M=(M1-M0);//Расчет количества тиков входной частоты за время измерения

Fx=12000000.0*(float)M/(float)N;//Вычисление частоты входного сигнала
putchar('c');
sprintf(lcd_buffer, "F=%0.6fHz", Fx);
lcd_clear();
lcd_puts(lcd_buffer);
puts(lcd_buffer);
putchar(13);
} }
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 10 2010, 06:02
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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

Еще одна ошибка у вас - gate сделайте volatile.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 10 2010, 09:01
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Цитата(Сергей Борщ @ Jun 10 2010, 10:02) *
Вы учитываете остаток в регистре таймера на момент окончания измерения, но не учитываете начальное значение таймера.

а как же
Код
N0=(((unsigned long int)(Perepol_Timer1_real))<<16)+count_T1;

вроде учитываю сount_T1...
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 10 2010, 21:36
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



У вас ошибка: второе прерывание TOV1 никогда не даст инкремента, поскольку GATE=0. Число N1 естественно будет меньше на 2^16.

Далее, счётчик T0 у вас 8-битный, а переменная count_T0 у вас int, ну и добавляете вы ее, как int, а надо только 8 бит. Для вашего компилятора может и пройдёт, но лучше по-честному добавлять 8-битное число.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 11 2010, 08:54
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Цитата(=GM= @ Jun 11 2010, 01:36) *
У вас ошибка: второе прерывание TOV1 никогда не даст инкремента, поскольку GATE=0. Число N1 естественно будет меньше на 2^16.

Таким образом пишем gate=0; после while ((TIFR&0x20)==0x20){}?
Цитата(=GM= @ Jun 11 2010, 01:36) *
Далее, счётчик T0 у вас 8-битный, а переменная count_T0 у вас int, ну и добавляете вы ее, как int, а надо только 8 бит. Для вашего компилятора может и пройдёт, но лучше по-честному добавлять 8-битное число.

а здесь пишем count_T0=(int)TCNT0; с приведением типа. (хотя компилятор сам это делает, не делает а пишет варнинги если написать char*2, например, то он ругнется на переполнение чара.)

В общем результат тот же. sad.gif И число N1 то меньше на 65536 то ровно столько сколько надо. От чего это зависит не понимаю. 3 измерения так - 3 так.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 11 2010, 21:28
Сообщение #6


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Структура вашей программы в некотором смысле эклектична.

1) Вроде бы работаете по прерываниям, но и ждёте флаг прерывания ICF1 в фоне, и явно это будет другое прерывание, поскольку по завершению прерывания флаг ICF1 сбрасывается в самом прерывании. Зачем тогда его ждёте?

2) В начале цикла измерения вы разрешаете прерывания по захвату, но не учитываете, что физически захват как молотил со скоростью входной частоты, так и молотит. Следовательно, после разрешения прерывания TOIE1=1 надо бы сбросить флаг ICF1, также и в конце измерения.

Кстати, каков диапазон частот вы хотите измерять, какой проц и тактовая?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 12 2010, 11:43
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Цитата(=GM= @ Jun 12 2010, 01:28) *
Структура вашей программы в некотором смысле эклектична.
Кстати, каков диапазон частот вы хотите измерять, какой проц и тактовая?

Да, программа такова, ибо сначала я пытался измерять методом ворот, но удачи не достиг smile.gif Вот код моего варианта:
Код
float result;
char buff[16], tim, numizm=2, state=0;

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
        tim++; // увеличиваем счетчик переполнений.
}

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
        if (state==0){  // первый фронт сигнала
                tim=0;  // обнуляем переменные и таймер
                TCNT1=0;
        }
        state++; // прибавляем счетчик
        if (state == numizm){ // если счетчик и кол-во измерений равны, то вычисляем частоту
                result = 12000000 / ((float)tim*65535+ICR1); // вычисляем "частоту"
                result *= (int)numizm; // и умножаем на кол-во измерений, получая действительную частоту

                numizm = 255; //выставляем число измерений
                if (numizm < result){ // если оно меньше полученной частоты то ставим ее равной частоте ( т.о. измерение будет длиться меньше секунды)
                        numizm = result;
                }                      
                sprintf(buff,"F = %0.3f Гц",result); // выводим на экран и в UART
                puts(buff);
                putchar(13);
                lcd_clear();
                lcd_puts(buff);
                state = 0; // Обнуляем состояние
        }                    
}

На мой взгляд совершенно логичный, но не работающий. Потом мне объяснили что таким способом, разрешающая способность будет не велика. Поэтому я решил пойти по пути Вашего метода. Ну и взял 2 варианта кода и их объединил smile.gif

Ну а частоты которые мне нужно измерять - 2 кГц -- 10 кГц. Насколько я понимаю, Вашим методом можно достичь очень хорошей точности, что для струнного датчика (линейный размер -> частота) было бы очень неплохо smile.gif

МК Atmega8 частота не принципиальна, но вот сейчас под рукой кварц на 12 мГц.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 12 2010, 12:51
Сообщение #8


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Для вашего случая погрешность измерения приблизительно будет +-0.0002 Гц без учёта нестабильности кварца. Вы не плодите варианты, а сконцентрируйтесь на первом, он вполне работоспособен. Как вы струну возбуждаете?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 12 2010, 21:51
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Цитата(=GM= @ Jun 12 2010, 16:51) *
Как вы струну возбуждаете?

Для этого используется автогенератор. На выходе его 300 мВ 2 -10 кГц прямоугольные импульсы. Но вообще эти старые железки хочется переделать и встроить в свое устройство.

Кстати говоря, вы своим вопросом породили во мне другой вопрос: можно ли использовать в Вашем алгоритме компаратор встроенный в мегу8 для захвата и будет ли его достаточно для детектирования столь низкого по амплитуде сигнала?
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 13 2010, 22:22
Сообщение #10


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(ps1x @ Jun 12 2010, 20:51) *
можно ли использовать в Вашем алгоритме компаратор встроенный в мегу8 для захвата и будет ли его достаточно для детектирования столь низкого по амплитуде сигнала?

В принципе, думаю можно, хотя оффсет у компаратора достаточно большой, посмотрите на рис. 167-168 док. 2486.

Думаю, что для ваших целей подойдёт более простой код для измерения частоты, это модификация вашего варианта, я только немного упорядочил и заменил названия "непроизносимых" переменных. Есть правда один нюанс, но об этом позже. Компилятор WinAVR-20100110
CODE
static float volatile Fx;
uint32_t volatile N,N1,N2,M,M1,M2;
uint16_t volatile mtick1,mtick2,mover=0;
uint16_t volatile ntick1,ntick2,nover=0;

ISR (TIMER0_OVF_vect) //переполнение счётчика0 входных тиков
{
mover++; //учтём в mover
}

ISR (TIMER1_OVF_vect) //переполнение таймера1 системных тиков
{
nover++; //учтём в nover
}

int main(void)
{
TIMSK=(1<<TOIE1)|(1<<TOIE0); //разрешим TOV1 и TOV0
asm volatile("sei\n\t":smile.gif; //разрешим прерывания
while(1) //цикл непрерывного измерения частоты
{
TIFR=(1<<ICF1); //сбросим флаг захвата
while((TIFR&0x20)==0x20); //ждём начала измерения
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в начале измерения
ntick2=nover;
mtick2=mover&0x00FF;
N1=((uint32_t)(ntick2)<<16)+(uint32_t) ntick1; //системные тики
M1=((uint32_t)(mtick2)<<8) +(uint32_t) mtick1; //входные тики
delay_ms(1000); //задержка на 1 с
TIFR=(1<<ICF1); //сбросим флаг захвата
while((TIFR&0x20)==0x20); //ждём конца измерения
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в конце измерения
ntick2=nover;
mtick2=mover&0x00FF;
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; //вычисление частоты входного сигнала

// <<здесь должен быть код вывода на индикатор>>

}
}


Обращаю внимание СИСАДМИНА: при редактировании тег [ / codebox ] самопроизвольно меняется на тег < / div >, возникает ошибка.

Сообщение отредактировал rezident - Jun 14 2010, 22:29
Причина редактирования: Редактирование тэгов цитаты исходника.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 14 2010, 18:46
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Цитата(=GM= @ Jun 14 2010, 02:22) *
В принципе, думаю можно, хотя оффсет у компаратора достаточно большой, посмотрите на рис. 167-168 док. 2486.

Но офсет ведь не влияет? Мы же начинаем измерение фронтом и заканчиваем, и теоретически, задержка прихода фронта не должна влиять. Естественно если она одна и та же для начала и окончания.

Спасибо за пример, единственно, надо будет разобраться с регистрами всяких настроек таймеров, прерываний и т.п. В CVAVR таких удобных обращений нет smile.gif

p.s. Правильны ли эти дефайны:
Код
#define TOIE0 0x01
#define TOIE1 0x04
#define ICF1 0x20

Судя по всему нет, ибо МК перезагружается на первой же строчке:
TIMSK=(1<<TOIE1)|(1<<TOIE0);
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 15 2010, 09:11
Сообщение #12


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



1) Оффсет влияет на начало фронта, многое зависит от ваших требований к изделию, пробуйте, потом расскажете. Если оффсет не изменяется за время измерения, то задержки обоих фронтов будут одинаковые.

2) Дифайны неправильные, надо так
Код
#define TOIE0 0
#define TOIE1 2
#define ICF1 5

Но самому делать ничего не надо, всё сделано до нас, определения находятся в одном из io*.h, для атмеги8 в частности в файле WinAVR-20100110\avr\include\avr\iom8.h.

Цитата(=GM= @ Jun 13 2010, 21:22) *
Обращаю внимание СИСАДМИНА: при редактировании тег [ / codebox ] самопроизвольно меняется на тег < / div >, возникает ошибка

Уважаемый rezident, спасибо за исправление, я тоже вначале так делал, но при этом искажается код программы, кроме того, вы разрушили моё красивое форматирование комментов, мне так не нравится. Обратите внимание, в исправленном вами коде вместо : : ) появилась заставка рожицы smile.gif. Это уже не дело, а ведь могут быть искажения и посерьёзнее, особенно там, где присутствуют угловые скобки < или >. Тогда уж не надо было вводить в практику и тег [ code ].

ЕЩЁ РАЗ ОБРАЩАЮ ВНИМАНИЕ: при редактировании сообщения тег [ / codebox ] самопроизвольно меняется на тег < / div >, приходится вручную забивать div и допечатывать codebox. При первом вводе сообщения такой замены не происходит. Похоже это баг системы, пожалуйста, разберитесь и по возможности исправьте.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 15 2010, 09:38
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



CODE
#include <mega8.h> //Подключение
#include <stdio.h> // внешнх
#include <stdlib.h>
#include <delay.h> // библиотек
#include <16x2.h>//

#define TOIE0 0
#define TOIE1 2
#define ICF1 5


//Объвление переменных
static float volatile Fx;
unsigned long volatile N,N1,N2,M,M1,M2;
unsigned int volatile mtick1,mtick2,mover=0;
unsigned int volatile ntick1,ntick2,nover=0;

//Прерывание по переполнению Timer/Counter 0
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
mover++;
}

//Прерывание по переполнению Timer/Counter 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void){
nover++;
}

//Тело основной программы
void main(void){

unsigned char lcd_buffer[46];//Обявление локальной строковой переменной

PORTC=0x00;
DDRC=0xFF;

//Инициализация Timer/Counter 0
TCCR0=0x07;

//Инициализация Timer/Counter 1

TCCR1B=0x01;


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

putsf("reset\r");
lcd_init();//Инициализация LCD HD44780

#asm("sei")

TIMSK=(1<<TOIE1)|(1<<TOIE0); //разрешим TOV1 и TOV0
putchar('a');

while (1){//Бесконечный цикл

TIFR=(1<<ICF1); //сбросим флаг захвата
putchar('b');
while((TIFR&0x20)==0x20); //ждём начала измерения
putchar('c');
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в начале измерения
ntick2=nover;
mtick2=mover&0x00FF;
N1=((long)(ntick2)<<16)+(long) ntick1; //системные тики
M1=((long)(mtick2)<<8) +(long) mtick1; //входные тики
putchar('d');
delay_ms(1000); //задержка на 1 с
TIFR=(1<<ICF1); //сбросим флаг захвата
while((TIFR&0x20)==0x20); //ждём конца измерения
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в конце измерения
ntick2=nover;
mtick2=mover&0x00FF;
N2=((long)(ntick2)<<16)+(long) ntick1; //системные тики
M2=((long)(mtick2)<<8) +(long) mtick1; //входные тики
N=N2-N1; //системные тики за время измерения
M=M2-M1; //входные тики за время измерения
Fx=12000000.0*(float)M/(float)N; //вычисление частоты входного сигнала
putchar('c');
sprintf(lcd_buffer, "F=%0.6fHz", Fx);
lcd_clear();
lcd_puts(lcd_buffer);
puts(lcd_buffer);
putchar(13);
} }


Это код который я гружу в контроллер.

CODE
bcdcF=1016.036315Hz

bcdcF=1017.031433Hz

bcdcF=1016.036315Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1016.036315Hz

bcdcF=1017.031433Hz

bcdcF=1016.036315Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1016.036315Hz

bcdcF=1017.031433Hz

bcdcF=1016.036315Hz

bcdcF=1016.036315Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1021.588439Hz

bcdcF=1016.036315Hz

bcdcF=1017.031433Hz

bcdcF=1016.036315Hz

bcdcF=1016.036315Hz

bcdcF=1021.588439Hz

bcdcF=1022.588989Hz

bcdcF=1021.588439Hz

bcdcF=1016.036315Hz

bcdcF=1016.036315Hz

bcdcF=1016.036315Hz

bcdcF=1016.036315Hz


А это то что на выходе в терминале.
smile3046.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 15 2010, 10:34
Сообщение #14


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



1) Для начала неплохо. Каков был номинал входной частоты?

2) Поставьте putchar('b'); до сброса флага захвата TIFR=(1<<ICF1); Вы должны понимать, что сбрасываете предыдущее состояние, которое возникло неизвестно когда, и ожидаете свежего захвата, после которого немедленно запоминаете свежие значения TCNT0 и ICR1, пока они не поменялись снова.

3) Из тех же соображений уберите вывод putchar('c'); сразу после захвата, это достаточно длительная функция.

4) Неплохо бы для отладки выводить в цикле не только частоту, но и значения N1, N2, M1, M2.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
ps1x
сообщение Jun 15 2010, 11:36
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 300
Регистрация: 15-03-06
Из: Москва
Пользователь №: 15 284



Входная частота 1019.02173 Гц. Расчетная. По осцилографу тоже очень похоже (С117 с метками).
CODE

reset
N1=0 M1=97
N2=0 M2=1130
cF=1016.924499Hz

N1=0 M1=1168
N2=0 M2=2204
cF=1014.423889Hz

N1=0 M1=2242
N2=0 M2=3277
cF=1018.893310Hz

N1=0 M1=3315
N2=0 M2=4350
cF=1018.893310Hz

N1=0 M1=4388
N2=0 M2=5423
cF=1018.893310Hz

N1=0 M1=5461
N2=0 M2=6496
cF=1018.893310Hz

N1=0 M1=6534
N2=0 M2=7569
cF=1018.893310Hz

N1=0 M1=7607
N2=0 M2=8642
cF=1018.893310Hz

N1=0 M1=8680
N2=0 M2=9715
cF=1013.444702Hz

N1=0 M1=9753
N2=0 M2=10788
cF=1018.893310Hz

N1=0 M1=10827
N2=0 M2=11863
cF=1014.423889Hz

N1=0 M1=11902
N2=0 M2=12939
cF=1020.862243Hz

N1=0 M1=12978
N2=0 M2=14014
cF=1019.877746Hz

N1=0 M1=14053
N2=0 M2=15089
cF=1019.877746Hz

N1=0 M1=15128
N2=0 M2=16164
cF=1014.423889Hz

N1=0 M1=16203
N2=0 M2=17240
cF=1020.862243Hz


Такое ощущение, что нужно обнулять nover и mover. Но что то еще не так.
Смущает так же, что N1 и N2 = 0.
Если обнулять nover и mover то измерения такие:
CODE

reset
N1=0 M1=98
N2=0 M2=1131
F=1016.924499Hz

N1=0 M1=144
N2=0 M2=1178
F=1017.908935Hz

N1=0 M1=191
N2=0 M2=1225
F=1017.908935Hz

N1=0 M1=238
N2=0 M2=1272
F=1017.908935Hz

N1=0 M1=29
N2=0 M2=1062
F=1022.421386Hz

N1=0 M1=75
N2=0 M2=1108
F=1016.924499Hz

N1=0 M1=121
N2=0 M2=1155
F=1017.908935Hz

N1=0 M1=168
N2=0 M2=1202
F=1017.908935Hz

N1=0 M1=215
N2=0 M2=1249
F=1017.908935Hz

N1=0 M1=6
N2=0 M2=1038
F=1021.431579Hz

N1=0 M1=51
N2=0 M2=1084
F=1016.924499Hz

N1=0 M1=97
N2=0 M2=1130
F=1016.924499Hz

N1=0 M1=143
N2=0 M2=1177
F=1023.411132Hz

N1=0 M1=190
N2=0 M2=1224
F=1017.908935Hz

N1=0 M1=237
N2=0 M2=1272
F=1024.400878Hz

N1=0 M1=29
N2=0 M2=1062
F=1016.924499Hz

N1=0 M1=75
N2=0 M2=1108
F=1016.924499Hz

N1=0 M1=121
N2=0 M2=1155
F=1017.908935Hz

N1=0 M1=168
N2=0 M2=1202
F=1017.908935Hz

N1=0 M1=215
N2=0 M2=1249
F=1017.908935Hz

N1=0 M1=6
N2=0 M2=1038
F=1015.940002Hz

N1=0 M1=51
N2=0 M2=1084
F=1016.924499Hz

N1=0 M1=97
N2=0 M2=1130
F=1022.421386Hz

N1=0 M1=143
N2=0 M2=1177
F=1017.908935Hz

N1=0 M1=190
N2=0 M2=1224
F=1017.908935Hz

А вот и сам код:
CODE
while (1){//Бесконечный цикл

TIFR=(1<<ICF1); //сбросим флаг захвата
while((TIFR&0x20)==0x20); //ждём начала измерения
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в начале измерения
ntick2=nover;
mtick2=mover&0x00FF;
N1=((long)(ntick2)<<16)+(long) ntick1; //системные тики
M1=((long)(mtick2)<<8) +(long) mtick1; //входные тики
sprintf(lcd_buffer, "N1=%i M1=%i\r", N1,M1);
puts(lcd_buffer);
delay_ms(1000); //задержка на 1 с
TIFR=(1<<ICF1); //сбросим флаг захвата
while((TIFR&0x20)==0x20); //ждём конца измерения
ntick1=ICR1; //запомним ICR1 и TCNT0
mtick1=TCNT0; //в конце измерения
ntick2=nover;
mtick2=mover&0x00FF;
N2=((long)(ntick2)<<16)+(long) ntick1; //системные тики
M2=((long)(mtick2)<<8) +(long) mtick1; //входные тики
sprintf(lcd_buffer, "N2=%i M2=%i\r", N2,M2);
puts(lcd_buffer);

N=N2-N1; //системные тики за время измерения
M=M2-M1; //входные тики за время измерения
Fx=12000000.0*(float)M/(float)N; //вычисление частоты входного сигнала

sprintf(lcd_buffer, "F=%0.6fHz", Fx);
lcd_clear();
lcd_puts(lcd_buffer);
puts(lcd_buffer);
putchar(13);
nover=0;
mover=0;
} }
Go to the top of the page
 
+Quote Post

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

 


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


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