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

три частоты на АТмегу 128 с использованием таймеров

Что касается отдельного таймера, то вы невнимательно читали мои посты, там как раз предлагается использовать отдельный таймер (timer/counter0) для подсчёта количества импульсов измеряемой частоты.

GM, дорогой, дискуссия была напряженной, но пора уже расслабиться. Я прочитал Ваши реплики не более невнимательно, чем Вы :) И я еще прочел автора темы - он хотел три частоты измерять. Рано или поздно таймеры могут закончиться. Успехов ;)

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


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

GM, дорогой, дискуссия была напряженной, но пора уже расслабиться. Я прочитал Ваши реплики не более невнимательно, чем Вы :) И я еще прочел автора темы - он хотел три частоты измерять. Рано или поздно таймеры могут закончиться. Успехов ;)

Уверен, они кончатся раньше(:-). А я, в основном, совершенно спокоен и расслаблен...до пятницы. На работе вынашиваю коварные планы, которые повергнут в шок братьев наших бледнолицых(:-).

 

Вообще притомился, собираюсь в отпуск...

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


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

m168, см comment #2

 

Во первых. Господа, Capture Unit для таких частот не пригодится. Capture Unit решает обратную задачу - измерение временных интервалов и чем меньше частота тем лучше. На частоте же 170Khz это будет всего ~100 тактов на период, точность будет мягко сказать хреновая при значительных затратах процессорного времени.

 

А теперь к самой задаче:

таймер T0 использовать в режиме External Clock source с прескейлером 1.

таймер T2 - в asyncronous режиме (тоже External clock) с прескейлером 1.

T1 16-ти разрядный оставить для отмерки секундных интервалов (и возможно каких-то других нужд)

к входу T0 подрубить сигнал 90khz

к входу T2 - 170khz

По прерыванию OVF увеличивать (на 256) значения 32-х разрядных счетчиков.

50khz мерять с помощью Int0 - в обработчике прерывания инкрементировать счетчик.

 

По прерыванию OC T1 (каждую секунду), прибавлять к счетчикам текущее значение таймеров T0, T2, сбрасывать таймеры T0, T2 и выводить рез-тат.

 

Точность будет +-1 Hz за секунду для всех 3х частот, плюс останется куча процессорного времени. Тобиш и частоту тактирования можно брать раза в два меньше.

 

PS: Кварц 22.1184 - фтопку, оверклок - неправильная затея.

 

 

 

От автора темы defunct

На 22-х мегагерцах атмеги 88 работают уже более полтора года

без срывов и подвисаний и сбоев :tongue:

АТмега168 ето оно же 88 талько чуть пузатее по памяти и всё

 

 

 

Я хочу попробовать померять частоты до ~50Mhz на AVR'кe без внешних компонентов.

 

Как для "метода захвата", так и для "метода ворот" имеется одно ФУНДАМЕНТАЛЬНОЕ ограничение - частота входного сигнала не может быть больше половины тактовой частоты процессора.

Так заметил GM и я с ним согласен.

Кстати, defunct, если видели АВРки с тактовой 100МГц то подскажите!!!

А в общем спасибо за ваши ответы.

Вы прочитали вопрос и ответили точно по самой сути.

 

А "слил", потому что рассуждать об измерении запредельных частот сейчас некогда

 

Почитать ваши ответы очень интересно и полезно начинающим.

А Ваш спор с GM весьма некоректный как с его стороны так и с Вашей.

Он (спор) больше напоминал базар в тюряге двух радиолюбителей подрывников. (Не сочтите за грубость). (Слово за слово, строка за строку и понесло....). Пжлста :a14: друг-друга.

Я Вас уважаю уже прочитав лиш ответы как знатока АВР, но всё же, моё мнение, GM и резидент прав

именно Capture Unit поможет добиться непревзойдённой точности.

"метод ворот" чудесен для высоких частот (неоспоримо).

И ёщё раз, я ВАМ ВСЕМ благодарен за сокращение времени поиска теории.

 

 

Справедливости ради стоит отметить, что диапазон измеряемых частот получается ограниченным сверху при сравнении с методом временных ворот, если только не использовать для подсчета количества импульсов измеряемой частоты отдельный таймер, а при увеличении количества измеряемых сигналов таймеров может и не хватить для каждого сигнала :)

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

С Вами я согласен полностью.

Тут всё понятно. Спасиб! :a14:

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


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

Как для "метода захвата", так и для "метода ворот" имеется одно ФУНДАМЕНТАЛЬНОЕ ограничение - частота входного сигнала не может быть больше половины тактовой частоты процессора.

Так заметил GM и я с ним согласен.

это ограничение действует на всю синхронную периферию. Но для асинхронного таймера поидее не важна частота процессора, собсно я и хочу испытать его возможности.

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


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

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

 

Вот вы написали "Оно сработало" в конце периода Т1 (ваши обозначения на рис.1). Что это означает? Это означает, что содержимое таймера1 от "мелкого" опорного меандра (который вы не нарисовали) переписалось в регистр ICR1, его надо запомнить, а прерывание запретить (в принципе, можно не запрещать, просто не обращать внимания, если время и вычислительная обстановка позволяет, важно, что нужно только первое, которое даёт время начала вашего окна).

 

Отмечу, что таймер1 продолжает работать, отсчитывает длительность окна. В начале времени Т2 на вашем рисунке надо разрешить прерывание опять, всё так, дождаться когда оно сработает (конец периода Т2 на вашем рисунке), и запомнить время, сохранённое в ICR1.

 

Затем нужно вычислить разность этих времен. Что нам даст эта разность? Эта разность N нам даст время (в тиках таймера1) между первым фронтом входной частоты и последним фронтом. Причём это время будет не приблизительным, а ТОЧНЫМ, с точностью ±1 такт. В то же самое время, таймер0 подсчитает количество импульсов входной частоты М. Теперь вы имеете на руках М, N и Fo и по формуле можете посчитать Fx.

 

Скажу ещё раз, для ясности. Сигнал измеряемой частоты надо подать на вход ICP1 и вход timer0/counter0, который работает как счётчик, в то же время timer1 работает как таймер, считает импульсы опорной частоты.

Спасиб за классное обяснение, учитывая частоты Ваш метод меня устроил

и для моего случая он отимален.

И ещё, мне кажется что Вы немножко спешите Всех критиковать за невнимательность

а сами тоже невнимательны.

Я извинился за неправильную постановку вопроса в названии контроллера,

defunct , правильно это заметил! это мой ответ резиденту в самом начале!!

 

m168, см comment #2

Что за comment #2? На заголовок темы посмотрите.

 

Да и приятно провести время в отпуске!!!

 

 

 

 

это ограничение действует на всю синхронную периферию. Но для асинхронного таймера поидее не важна частота процессора, собсно я и хочу испытать его возможности.

Вприцыпе, идея интересна потому только что я не знаю как работать с асинхронным таймером

и его возможностями. С внешним счётчиком видел где-то схему частотомера на 2313том до 40МГц.

Желаю удачи!

 

 

это ограничение действует на всю синхронную периферию. Но для асинхронного таймера поидее не важна частота процессора, собсно я и хочу испытать его возможности.

Взял описсание злостной АТмеги 168 таймер 2 и выделил два момента:

  • The CPU main clock frequency must be more than four times the Oscillator

During asynchronous operation, the synchronization of the Interrupt Flags for the asynchronous

timer takes 3 processor cycles plus one timer cycle. The timer is therefore

advanced by at least one before the processor can read the timer value causing the setting

of the Interrupt Flag. The Output Compare pin is changed on the timer clock and is

not synchronized to the processor clock.

Вашу идею не совсем понимаю.

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


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

То sKWO

 

Не знаю, есть ли АВРки с тактом 100 Мгц, а вот с тактом 48 МГц пожалуйста - АТ76С712 и 713.

 

Успехов в трудном деле измерения частоты. И напоследок: не давайте далеко заплывать плавающей запятой(:-).

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


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

То =GM=

 

Очень заинтересовал ваш метод измерения частоты.

Интересует следующие. Вы писали, что таймер1 считает такты МК, собственно вопрос: как лучше опрабатывать переполнение по пррыванию или следить программно.

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


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

То =GM=

 

Очень заинтересовал ваш метод измерения частоты.

Интересует следующие. Вы писали, что таймер1 считает такты МК, собственно вопрос: как лучше опрабатывать переполнение по пррыванию или следить программно.

Помнитца где-то около года назад мы уже обсуждали эту тему,

кажись тогда она называлась типа: ловля импульсов с 1мкс точностью на кварце МГц. :)

Название конечно переврал, но поиском должно искаться.

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


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

То =GM=

Очень заинтересовал ваш метод измерения частоты.

Интересует следующее. Вы писали, что таймер1 считает такты МК, собственно вопрос: как лучше обрабатывать переполнение по прерыванию или следить программно.

Зависит от задачи, но особой разницы нет, без прерываний проц будет тупо ждать наступления переполнения, следовательно, ничего другого сделать не сможет. Хотя, по своему опыту скажу, что и здесь можно вывернуться, у меня было несколько реализаций метода захвата без прерываний ( т.к. были жесткие требования по джиттеру), частота мерялась от 0.5 МГц до 1.5 МГц, так я и датчик температуры по одному проводу опрашивал и много ещё чего там делалось.

 

По прерываниям, ваш проц в фоне может вычислить частоту, по данным, полученным в предыдущем цикле.

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


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

Спасибо. Всь сыр бор вот в чем, как Вы могли уже заметить я создал тему связаную с переполнением таймера0, поэтому и спрашивал как лучше.

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


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

ТО GM

Для работы частотомера по Вашому методу контроллер обязательно должен иметь два таймера с Capture Unit? Я вот хотел сделать на ATmega8L, но что то не то, точность оставляет желать лучшего.

Вот код, подскажите что не так. Спасибо.

#include <mega8.h>

static float Fx;
unsigned long int N1, N;
unsigned int M1, M;
unsigned int Perepol_Timer0=0, Perepol_Timer1=0;
unsigned int count_T1, count_T0;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void){
Perepol_Timer0++;
}

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void){
Perepol_Timer1++;
}

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void){
TIMSK&=0xDF;
count_T0=TCNT0;
count_T1=ICR1;
} 


void main(void)
{
// Input/Output Ports initialization

PORTB=0x00;
DDRB=0x00;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: T0 pin Rising Edge
TCCR0=0x07;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Rising Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x41;
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
MCUCR=0x00;

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

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

// Global enable interrupts
#asm("sei")
while (1) {
Perepol_Timer1=0;
N1=Perepol_Timer1*65535+count_T1;
M1=Perepol_Timer0*255+count_T0;
while (Perepol_Timer1<12){
};
TIMSK|=0x20;
N=((unsigned long int)(Perepol_Timer1)*65535+(unsigned int)(count_T1))-N1;
M=(Perepol_Timer0*255+count_T0)-M1;
Fx=(float)8000000.0*(float)M/(float)N;
};
TIMSK|=0x20;
}

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


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

То GM Для работы частотомера по Вашему методу контроллер обязательно должен иметь два таймера с Capture Unit? Я вот хотел сделать на ATmega8L, но что-то не то, точность оставляет желать лучшего

Достаточно одного.

Вот код, подскажите что не так. Спасибо

Во-первых, счётчики переполнений надо умножать на 65536 и 256 соответственно, а не так как у вас.

Во-вторых, у вас прерывание по захвату сработает на второй перепад, скажем частота 1 МГц, значит через 1 мкс, а вам надо ждать примерно 1 секунду. Кстати, частота вычислится, но точность будет никакая, поскольку определение частоты будет происходить по одному периоду(:-(.

 

Примерный алгоритм бесконечного цикла может быть следующим.

1) ждём 1с,

2) разрешили захват,

3) дождались захвата,

4) считали N2 и M2,

5) вычислили Fx и выдали на индикатор,

6) передвинули метку времени: N1=N2, M1=M2,

7) вернулись к пункту 1.

 

Код примерно такой.

Perepol_Timer1=0;  //внимание, первое значение частоты может быть неточным
N1=0;M1=0;
while (1)
{
while ((currenTime-oldTime)<OneSec)    //п.1-условно, можно сделать по-другому
{
}
TIMSK|=0x20;                           //п.2-разрешили захват
while ((TIMSK&0x20)==0x20)             //п.3-условно, можно сделать по-другому
N2=((unsigned long int)(Perepol_Timer1))*65536+count_T1; //п.4-текущее время
M2=Perepol_Timer0*256+count_T0;
N=N2-N1;                               //п.5-вычисление частоты
M=M2-M1;
Fx=(float)8000000.0*(float)M/(float)N; //можно выдать во внешний мир
N1=N2;                                 //п.6-новое значение времени стало старым
M1=M2;
}                                     // <---while цикл---

В-третьих, я удивлён, как оказывается легко "метод захвата" реализовать на си(:-). Well done!

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


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

Умножение на 256 и 65536 имеет смысл заменить сдвигами. И перед делением стоит проверить значение N на нуль, чтобы избежать исключения (ошибка деления на нуль).

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


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

Умножение на 256 и 65536 имеет смысл заменить сдвигами. И перед делением стоит проверить значение N на нуль, чтобы избежать исключения (ошибка деления на нуль).
Насчёт деления всё верно, проверять надо. А на асме и сдвигать не надо, просто положить значение в соответствующую ячейку или регистр. Вот интересно, какую максимальную частоту сможет измерить сишная программа?

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


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

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

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

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

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

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

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

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

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

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