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

 
 
> MegaAVR, Timer
Duduka
сообщение Feb 28 2007, 11:49
Сообщение #1





Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758



[font=Times New Roman][size=4]
Привет, всем посетителям форума!
Возникла проблема с мегой 128...Может кто-нибудь из специалистов обратит внимание и разъяснит неопытному пользователю в чем проблема?

А вопрос в следующем...пытаюсь измерить период с точностью до 0,1 мкс. Для этого задействована пара счетчиков (вариантов уже накопилось множество, поэтому прикладываю самый простой на, мой взгляд). Измеряемый диапазон частот 600 Гц-2,5 кГц

Используется два таймера:
-Т/С0-генерирует 102, 4 кГц, при каждом совпадении счетного регистра осуществляется инкремент регистров-результата;
-Т/С2-считает импульсы с датчика-для обеспечения заданной точности 100*Т .
Как только досчитали до 100 останавливаем , обнуляем таймеры и передаем по ком порту на комп.
Мегу тактирую 7,3728 МГц (реально 7,3724 МГц)

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

Работаю с STK500/501, AVR Studio 4.12 и самодельным Jtag ICE.
В качестве сигнала с датчика использую кварц STK500.
Прикрепленные файлы
Прикрепленный файл  mega128.rar ( 1.74 килобайт ) Кол-во скачиваний: 100
 
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
IgorKossak
сообщение Feb 28 2007, 11:55
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Duduka @ Feb 28 2007, 10:49) *
Используется два таймера:
-Т/С0-генерирует 102, 4 кГц, при каждом совпадении счетного регистра осуществляется инкремент регистров-результата;
-Т/С2-считает импульсы с датчика-для обеспечения заданной точности 100*Т .
Как только досчитали до 100 останавливаем , обнуляем таймеры и передаем по ком порту на комп.
Мегу тактирую 7,3728 МГц (реально 7,3724 МГц)

Приведите фрагмент кода.
Go to the top of the page
 
+Quote Post
Duduka
сообщение Feb 28 2007, 13:11
Сообщение #3





Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758



[font=Times New Roman][size=4]

А прикрепленный файл не подходит?
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 28 2007, 13:42
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



1. Прерывание OC2addr_int: не содержит инструкции reti или я что-то не понял?
2. В прерывании OC0addr_int: строка cpi numberL,0xFF явно лишняя.
3. С Вашими настройками нулевого таймера полная каша. Проверьте то ли Вы пишете и в те ли регистры.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 28 2007, 14:17
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Прерывания ни когда не дадут точный временной интервал. В зависимости от применяемых в программе команд у вас будет дрожание от 1 до 3 тактов. На частоте 7.3728 это составит от 0.136 до 0.4 мкс соответственно.

Для измерения точных интервалов требуется

1) "ворота генерировать аппаратным способом. На худой конец можно попробовать с помощью таймера, но с аппаратным выводом по OC1A к примеру или на другую ножку. То есть ворота должны быть сформированы аппаратно!
2) чтение можно осуществлять ч/з ворота по захвату (например ч/з ic3a).

Необходимо учесть, что максимальная частота читаемая с входа не должна превышать fclk/2. В случае превышения ставится аппаратный делитель запираемый теми же воротами и значение с него выводятся на порт.

для измерения периода сигнала - подход тот же только ворота - исследуемый сигнал.

Соответственно формируем аппаратно частоту заполнения и подаём ч/з ворота на вход захвата. Если частота велика, то пропускаем ч/з счётчик. Если скважность меньше двух, то необходима ещё схема типа запускаемого одновибратора, с целью успеть считать данные до момента повторного открытия ворот.

Прерывания могут быть только по переполнению.
Go to the top of the page
 
+Quote Post
Duduka
сообщение Feb 28 2007, 17:15
Сообщение #6





Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758



Цитата(IgorKossak @ Feb 28 2007, 13:42) *
1. Прерывание OC2addr_int: не содержит инструкции reti или я что-то не понял?
2. В прерывании OC0addr_int: строка cpi numberL,0xFF явно лишняя.
3. С Вашими настройками нулевого таймера полная каша. Проверьте то ли Вы пишете и в те ли регистры.


По поводу прерывания: да инструкции действительно нет, но там есть команда

rjmp wait_write

но при таком выходе из п/п мне следовало бы заново проинициализировать стек?!

По поводу лишней строчки согласна, т.к. проверяю состояние флага Z.

А вот, что за каша в настройках нулевого таймера??

out ASSR,zero; выбираем синхронный режим
ldi temp,0x23 ; модуль счета
out OCR0,temp ;
ldi temp,0x99 ; режим работы
out TCCR0,temp ;
out TCNT0,zero ; обнуляем счетный регистр

В чем ошибка?
Go to the top of the page
 
+Quote Post
Duduka
сообщение Feb 28 2007, 18:03
Сообщение #7





Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758



Цитата(SasaVitebsk @ Feb 28 2007, 14:17) *
Прерывания ни когда не дадут точный временной интервал. В зависимости от применяемых в программе команд у вас будет дрожание от 1 до 3 тактов. На частоте 7.3728 это составит от 0.136 до 0.4 мкс соответственно.

Для измерения точных интервалов требуется

1) "ворота генерировать аппаратным способом. На худой конец можно попробовать с помощью таймера, но с аппаратным выводом по OC1A к примеру или на другую ножку. То есть ворота должны быть сформированы аппаратно!
2) чтение можно осуществлять ч/з ворота по захвату (например ч/з ic3a).

Необходимо учесть, что максимальная частота читаемая с входа не должна превышать fclk/2. В случае превышения ставится аппаратный делитель запираемый теми же воротами и значение с него выводятся на порт.

для измерения периода сигнала - подход тот же только ворота - исследуемый сигнал.

Соответственно формируем аппаратно частоту заполнения и подаём ч/з ворота на вход захвата. Если частота велика, то пропускаем ч/з счётчик. Если скважность меньше двух, то необходима ещё схема типа запускаемого одновибратора, с целью успеть считать данные до момента повторного открытия ворот.

Прерывания могут быть только по переполнению.


Если я правильно понимаю, пусть:

-Т/С0- генерирует импульсы заполнения ...пусть 102,4 кГц, которые можно "снимать" с выхода ОС0 и пдавать на другой счетчик.
-Т/С2 организует временные ворота, на его вход поступают импульсы с датчика, считает до 100, сбрасывается, меняется значение на выходной ножке, по которому счетчик, считающий импульсы заполнения, сохраняет полученные значения;
-Т/С3- собственно считает импульсы заполнения.

Так?
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 28 2007, 18:17
Сообщение #8


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(Duduka @ Feb 28 2007, 16:15) *
По поводу прерывания: да инструкции действительно нет, но там есть команда

rjmp wait_write

но при таком выходе из п/п мне следовало бы заново проинициализировать стек?!

Да если бы только в этом дело. Сейчас может этого и хватит, но при минимальном развитии программы такой подход крайне неэлегантен. Поэтому подпрограммы и прерывания (особенно) желательно завершать штатным образом. Да и на С в будущем проще будет портировать.
Цитата(Duduka @ Feb 28 2007, 16:15) *
По поводу лишней строчки согласна, т.к. проверяю состояние флага Z.

Строчка не столько лишняя, сколько ошибочная, т. к. инкремент старшей части надо делать при переходе младшей в 0х00, а не в 0xFF.
Цитата(Duduka @ Feb 28 2007, 16:15) *
А вот, что за каша в настройках нулевого таймера??

out ASSR,zero; выбираем синхронный режим
ldi temp,0x23 ; модуль счета
out OCR0,temp ;
ldi temp,0x99 ; режим работы
out TCCR0,temp ;
out TCNT0,zero ; обнуляем счетный регистр

В чем ошибка?

Здесь я имел в виду навороченность настроек TCCR0.
На мой взгляд управлять выходом OC0 нет необходимости, т. к. Вы принудительно дёргаете shinad,inter0. Настройка в этом случае будет выглядеть как ldi temp,0x09.
Проверьте, может я и не прав.
Go to the top of the page
 
+Quote Post
Duduka
сообщение Feb 28 2007, 19:21
Сообщение #9





Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758



Да, вы правы, ненчего лишний раз дергать вывод...
но так как мне хотелось видеть (для проверки), что генерирует счетчик, думаю в таком случае
ldi temp,0x19.

Спасибо за ваши советы! Только вот общий вопрос по теме остается неразрешенным...погрешность каким-то образом зависит от количества выполняемых инструкций между пуском и остановкой счетчиков??
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 28 2007, 23:48
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Duduka @ Feb 28 2007, 12:49) *
А вопрос в следующем...пытаюсь измерить период с точностью до 0,1 мкс. Для этого задействована пара счетчиков (вариантов уже накопилось множество, поэтому прикладываю самый простой на, мой взгляд). Измеряемый диапазон частот 600 Гц-2,5 кГц


Давайте переведём 600 Гц - период 1666.7мкс (411Ah единиц с шагом 0.1мкс)
2.5кГц - 400.0 (FA0h единиц с шагом 0.1мкс)

Таким образом вам необходимо посчитать импульсы частотой 1/0.1мкс = 10МГц и для этого достаточно 16-ти битного таймера. Из приведенного видно что на частоте 7372800 вы не получите данную точность без внешних элементов.

Необходимо применить кварц с частотой не менее 10МГц.

Если мы применим кварц 10 МГц, то необходимо следующее.

1) Настроить выход меги в режиме генерации CLK.
2) Применить 1533ли1 к примеру (Если мерим длит. положительного импульса). Если надо определять что мерить полож или отриц, то незначительно сложнее не всё поместится на одной ЛА3 или 74hc00.
3) Измеряемый сигнал подать на 1 ногу а заполнение на вторую. С выхода (третья нога) на вход захвата шеснадцатибитного таймера (например IC1A).
4) Также измеряемый сигнал подаём на вход INT0 к примеру.
5) Настраиваем прерывание от INT0 на прерывание по перепаду в 0.
6) Настраиваем таймер один канал а на захват.

Алгоритм измерения следующий.
По прерыванию от Int0 (конец полож импульса измеряемого сигнала - измерение закончилось) мы читаем значение ICR1A, что и является значением периода измеренного сигнала (можно выводить). И сбрасываем значение ICR1A таймера (начинаем новый отсчёт)



Программу вашу не читал. Пока без надобности. Необходимо что бы вы сами поняли что хотите сделать и внятно смогли другим объяснить.




Да... упустил одну деталь которую сам же и писал... smile.gif

На частоте 10MHz ваша однокристалка не сосчитает импульсы 10MHz. По этому изменения следующие (тоже писал в предыдущем посте).

Между выходом мелкосхемы и счётным входом однокристалки необходимо поставить доп счётчик. К примеру ИЕ7 а его выходы (4 штуки) на свободные входы однокристалки. При чтении необходимо читать ICR1A (старшие 16 разрядов) и входы счётчика (младшие 4). В остальном нет отличий.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Mar 1 2007, 00:59
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984



Саша ,у таймера есть прерывание по захвату,так что все шаманство с INT можно отбросить,
счетчик посчитает импульсы ,но не решит проблемы с их длиной ,тут правда не ясно ,что важнее ,посчитать частоту или длину.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Mar 1 2007, 10:55
Сообщение #12


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Действительно, варианта с Input Capture было бы вполне достаточно.
При этом реакция на прерывание должна уложиться в 200 мкс, чего хватит с головой даже в случае применения вытесняющей RTOS в проекте.
Поскольку задача решается аппаратно, то от времени сидения программы в прерывании погрешность не зависит.
Ну и кварц, разумеется должен быть не менее 10 МГц (в идеальных условиях), а лучше 16 МГц.
Рассуждения здесь следующие. Поскольку средство Input Capture синхронизируется тактовой частотой МК, то погрешность отлавливания фронта (или спада) импульса может достигать 0,1 мкс (на 10 МГц). Для измерения периода таких событий нужно два. Поэтому в худшем случае будет 0,2 мкс при тех же 10 МГц.
Это так, навскидку, без применения сложных статистических методов.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 2 2007, 00:02
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Согласен с обоими. Конечно любой разработчик при заказе 0.1 уменьшит для надёжности. Писал на скорую руку перед рыбалкой. Хотя быть может это уже с запасом.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Mar 2 2007, 02:30
Сообщение #14


Ambidexter
*****

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



Поскольку входной сигнал асинхронен по отношению к системной частоте, погрешность измеряемого периода может достигать плюс-минус одного клока. При клоке=10 Мгц это будет плюс-минус 0.1 мкс.

Так что измерения с точностью 0.1 мкс (фактически +-0.05 мкс) можно достичь только с частотой заполнения 20 МГц.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 2 2007, 03:32
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(=GM= @ Mar 2 2007, 03:30) *
Поскольку входной сигнал асинхронен по отношению к системной частоте, погрешность измеряемого периода может достигать плюс-минус одного клока. При клоке=10 Мгц это будет плюс-минус 0.1 мкс.

Так что измерения с точностью 0.1 мкс (фактически +-0.05 мкс) можно достичь только с частотой заполнения 20 МГц.


Я понимаю о чём вы пишете.

Да действительно. Можно конечно пробовать уменьшить данную ошибку программно. Хотя это будет громоздко.

Тем не менее в неинтелектуальных частотомерах обычно используется заполнение удобное для счёта. Наверное они вводят инструментальную погрешность в 2 единицы заполнения.

Как выход здесь можно использовать внешний генератор меток на 20Мгц. С одним счётчиком достаточно использовать мегу на 7372800
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 11:27
Рейтинг@Mail.ru


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