|
MegaAVR, Timer |
|
|
|
Feb 28 2007, 11:49
|
Группа: Новичок
Сообщений: 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.
|
|
|
|
|
Feb 28 2007, 13:11
|
Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758

|
[font=Times New Roman][size=4]
А прикрепленный файл не подходит?
|
|
|
|
|
Feb 28 2007, 17:15
|
Группа: Новичок
Сообщений: 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 ; обнуляем счетный регистр В чем ошибка?
|
|
|
|
|
Feb 28 2007, 18:03
|
Группа: Новичок
Сообщений: 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- собственно считает импульсы заполнения. Так?
|
|
|
|
|
Feb 28 2007, 18:17
|

Шаман
     
Группа: Модераторы
Сообщений: 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. Проверьте, может я и не прав.
|
|
|
|
|
Feb 28 2007, 19:21
|
Группа: Новичок
Сообщений: 12
Регистрация: 28-02-07
Пользователь №: 25 758

|
Да, вы правы, ненчего лишний раз дергать вывод... но так как мне хотелось видеть (для проверки), что генерирует счетчик, думаю в таком случае ldi temp,0x19.
Спасибо за ваши советы! Только вот общий вопрос по теме остается неразрешенным...погрешность каким-то образом зависит от количества выполняемых инструкций между пуском и остановкой счетчиков??
|
|
|
|
|
Feb 28 2007, 23:48
|
Гуру
     
Группа: Свой
Сообщений: 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 таймера (начинаем новый отсчёт) Программу вашу не читал. Пока без надобности. Необходимо что бы вы сами поняли что хотите сделать и внятно смогли другим объяснить. Да... упустил одну деталь которую сам же и писал... На частоте 10MHz ваша однокристалка не сосчитает импульсы 10MHz. По этому изменения следующие (тоже писал в предыдущем посте). Между выходом мелкосхемы и счётным входом однокристалки необходимо поставить доп счётчик. К примеру ИЕ7 а его выходы (4 штуки) на свободные входы однокристалки. При чтении необходимо читать ICR1A (старшие 16 разрядов) и входы счётчика (младшие 4). В остальном нет отличий.
|
|
|
|
|
Mar 1 2007, 10:55
|

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

|
Действительно, варианта с Input Capture было бы вполне достаточно. При этом реакция на прерывание должна уложиться в 200 мкс, чего хватит с головой даже в случае применения вытесняющей RTOS в проекте. Поскольку задача решается аппаратно, то от времени сидения программы в прерывании погрешность не зависит. Ну и кварц, разумеется должен быть не менее 10 МГц (в идеальных условиях), а лучше 16 МГц. Рассуждения здесь следующие. Поскольку средство Input Capture синхронизируется тактовой частотой МК, то погрешность отлавливания фронта (или спада) импульса может достигать 0,1 мкс (на 10 МГц). Для измерения периода таких событий нужно два. Поэтому в худшем случае будет 0,2 мкс при тех же 10 МГц. Это так, навскидку, без применения сложных статистических методов.
|
|
|
|
|
Mar 2 2007, 03:32
|
Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|