Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Измерение временных интервалов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2, 3
AVR
Здравствуйте!
Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает...
WHALE
C точностью до микросекунды с кварцем на 1Мгц никак.
GetSmart
А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?
rezident
Цитата(GetSmart @ Jun 2 2006, 23:10) *
А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?

А считывать значения периода с разрешением 1мкс при тактовой 1МГц он будет успевать? smile.gif
GetSmart
Цитата
C точностью до микросекунды с кварцем на 1Мгц никак.

А я бы сказал - элементарно, но на AVR. Для PIC не знаю точно, есть у них функция захвата и есть ли делитель у таймера? То есть инкрементируется таймер от 1 МГц или от делителя 1/4 или ещё как. Если от 1 МГц и есть захват, то этого достаточно. Ну и интервал не должен быть очень маленьким. Внутри него должно успеть обработаться прерывание.
AVR
Цитата(GetSmart @ Jun 2 2006, 21:10) *
А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?
Можно подробнее чуточку? Какие старшие 16 бит? Подскажите, пожалуйста, как это можно сделать?
Я пытался реализовать это так:
По внешнему прерыванию ставлю таймер в режим сравнения на 50К (+обнуление по переполнению) и по прерыванию увеличиваю значение 32-битной переменной в ОЗУ на эти самые 50к. После ещё одного внешнего прерывания останавливаю таймер и остаток (содержимое TCNTn) добавляю к этой же переменной (после чего обнуляю TCNTn). Но: в результате, хоть я и подаю на вход импульсы постоянной длительности, значения на выходе пляшут как будет бы у меня генератор случайных чисел =(
GetSmart
Чё-то я ослеп. Речь как раз об AVR. Берёте Мегу8, она с захватом. Всё получится с точностью 1 мкс, если интервалы будут хотя бы 10 и более мкс. Это если писать на асме. Если на си, то раза в 3 большие интервалы.

Вроде бы правильно делаете. Может какая мелкая ошибка. Прикрепите исходник, я посмотрю. Кстати, когда обнуляете таймер, обнуляете ещё переменную?
defunct
Цитата(GetSmart @ Jun 2 2006, 20:43) *
Чё-то я ослеп. Речь как раз об AVR. Берёте Мегу8, она с захватом. Всё получится с точностью 1 мкс, если интервалы будут хотя бы 10 и более мкс. Это если писать на асме. Если на си, то раза в 3 большие интервалы.

Вроде бы правильно делаете. Может какая мелкая ошибка. Прикрепите исходник, я посмотрю. Кстати, когда обнуляете таймер, обнуляете ещё переменную?


Получится, но с одной оговоркой:

не всегда будет указанная точность.

Нельзя выйти на точность в 1мкс в случае когда прерывание таймера "по захвату" сработает одновременно с прерыванием таймера "по переполнению" либо по "сравнению" для увеличения старшей части 32-х битного счетчика времени.


Цитата
Можно подробнее чуточку? Какие старшие 16 бит? Подскажите, пожалуйста, как это можно сделать?

Пример, с учетом того, что Timer1 уже настроен на работу в режиме Input Capture с генерацией прерываний по CAPT и по OVF.
В таком виде как в примере - нельзя выполнять команды условного перехода и арифметические команды в основном цикле программы.


Код
.def  AL = R24
.def  Const0 = R8
.def  Const1 = R9

....
   ldi  AL, 1
   mov  Const1, AL
   clr  Const0
...

; обработчик Input Capture:
TIM1_CAPT:
    in    R4, ICR1L
    in    R5, ICR1H
    mov   R6, R2
    mov   R7, R3
    tst   R5
    brne  _do_not_correct_result
    in    AL, TIFR
    andi  AL, (1 << TOV1)
    breq  _do_not_correct_result
    add   R6, Const1
    adc   R7, Const0
_do_not_correct_result:
; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7)
    reti
    

; обработчик Timer Overflow:
TIM1_OVF:
     add R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика
     adс R3, Const0; учет переноса.
     reti
GetSmart
Цитата
Нельзя выйти на точность в 1мкс в случае когда прерывание таймера "по захвату" сработает одновременно с прерыванием таймера "по переполнению" либо по "сравнению" для увеличения старшей части 32-х битного счетчика времени.

Ну почему же? Захват же аппаратный. Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению. А если захват аппаратный и прерывание по переполнению, то таймер никогда не останавливается и "захватывается" точное значение. Поэтому я бы рекомендовал делать прерывание именно по переполнению.
defunct
Цитата(GetSmart @ Jun 2 2006, 22:51) *
Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению.

Да все так, доп проверка для ((ICR > 0) и (ICR < длительность обработчика OVF))
Все равно есть ситуации где точность 1mks на двух прерываниях обеспечить не реально.
Ну представьте захвачен ICR = 0.
Что делать? Было отработано прерывание по переполнению или нет? А бог его знает. Если CAPT сработал в момент перехода на обработку OVF - то было, если раньше - то не было. А теряется не много ни мало всего лишь 64k mks ;>

т.е. думаю нужно вводить еще прерывание OC, с OCR = 64k/2, чтобы точно знать о природе ICR=0.
GetSmart
Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.
defunct
Цитата(GetSmart @ Jun 2 2006, 23:54) *
Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.

Действительно a14.gif
"А ларчик то просто открывался" smile.gif

(подправил код примера с учетом Вашего последнего поста.)
GetSmart
Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить.
defunct
Цитата(GetSmart @ Jun 3 2006, 00:18) *
Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить.

Там это учтено:

tst r1
brne ...
GetSmart
Цитата
Там это учтено:

Да, я это написал когда ещё не было.

Кстати, 16 бит таймера и 8 старших бит счётчика в регистре дадут уже период в 16 секунд. Может этого будет достаточно?
defunct
Цитата(GetSmart @ Jun 3 2006, 00:53) *
Кстати, 16 бит таймера и 8 старших бит счётчика в регистре дадут уже период в 16 секунд. Может этого будет достаточно?


Немного изменил код, счетчик не сбрасывается, а постоянно накапливается. Результатом измерения будет разность между двумя захватами. А в такой реализации 8 бит может быть недостаточно.
Таймер (TCNT) конечно можно корректировать в обработчике CAPT, но это IMHO будет некрасивое решение.
GetSmart
Вроде нормальный пример. Тока непонятно зачем R0 и R1 используются.

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


Хотя... постойте... В прерывании OVR инкрементируются R3:R2, которые потом копируются в R7:R6. Однако при отложенном прерывании OVR почему-то у Вас инкрементируется не R7:R6, а R4 и далее по списку.
GetSmart
???
Rst7
О чем вы, господа? Забыли, что внутри проца есть еще синхронизация пина? т.е. 1-2 такта задержки вам обеспечено.. Что больше необходимой 1мкс (при тактовой 1МГц).
GetSmart
О чём вы, господин? Задержка всегда постоянная. И для двух фронтов она компенсирует друг друга.
Rst7
Э, да, вспылил, был неправ wink.gif
defunct
Цитата(GetSmart @ Jun 3 2006, 02:02) *
Хотя... постойте... В прерывании OVR инкрементируются R3:R2, которые потом копируются в R7:R6. Однако при отложенном прерывании OVR почему-то у Вас инкрементируется не R7:R6, а R4 и далее по списку.

Ой.. и правда.
Успел отредактировать ;>
Валентиныч
А чем вызвано ограничение по кварцу - 1 МГц? (Или я проглядел?)
При расширении разрядности таймера до 24-32 разрядов (да хоть до 64-х! biggrin.gif ) увеличение тактовой до 8-16 МГц резко увеличит точность при сокращении времени измерения.
GetSmart
defunct
Ну ёкарный бабай...
Ещё нужно заменить "tst R1; brne ..." на "tst R5; brmi ..."
Поясню почему. Дело в том, такая конструкция допускает ещё другие, длительные прерывания (до 32к тактов). При этом конечно периоды импульсов должны быть ещё больше. Вобщем мне кажется, что так более логично и идеальнее алгоритм.

Не понимаю как Вам удаётся менять посты без надписи "отредактировано"?!
defunct
Цитата(GetSmart @ Jun 3 2006, 20:16) *
defunct
Ну ёкарный бабай...
Ещё нужно заменить "tst R1; brne ..." на "tst R5; brmi ..."
Поясню почему. Дело в том, такая конструкция допускает ещё другие, длительные прерывания (до 32к тактов). При этом конечно периоды импульсов должны быть ещё больше. Вобщем мне кажется, что так более логично и идеальнее алгоритм.

R1 на R5 заменил!
Насчет brmi - на любителя, но я все же предпочитаю brne. 256 тактов и так предостаточно. Все таки задача мерять интервалы времени с точностью 1mks, а не принимать антикризисные меры по оживлению программы с курса ...123 в котором задержка в обработчике прерывания на 20ms считается нормальным явлением. Длительные прерывания - от лукавого, никогда такого не делаю и никому не советую.

Цитата
Не понимаю как Вам удаётся менять посты без надписи "отредактировано"?!

Полная правка?

ps: извиняюсь за мою невнимательность и небрежность при написании примера. GetSmart пожалуйста, если там еще что-то заметите, просто внесите Ваши исправления и запостите отдельным сообщением. (а то как-то неудобно уже постить на эту тему и бесконечно править 10 строчек кода) smile.gif
Sergiy
все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.

Да, еще раз задам вопрос, почему выбрана частота - 1МГц, может парень просто хочет пользовать калиброванную RC-цепочку в качестве задатчика частоты smile.gif.

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

Так вот парень хочет мерять интервалы времени в секунды (единицы например) при точности в 1мкс, если я правильно понял, имеем на лицо требуемую точность менее 1ppm. Теперь открываем паспортные данные на самые лучшие кварцы ширпотреба или даже проф. Ну что поняли мысль или нет. Ну если мы возмем эталоны частоты (времени) на радиоизотопах, термостабилизированные, состаренные и так далее - ну тогда мы будем говорить, но знаете скока стоит такая каробочка. Может все таки надо пересмотреть точность. Или сказать что девайс будет использоваться в очень узком температурном диапазоне, и к этому будет калиброваться раз в месяц эталонном. Тогда можно говорить о реализации программы в АВР, хотя я бы сказал, что частоту все таки надо повысить, чтобы хотя бы тут на элементарном не терять.

Кто не согласен со мной, спорить не буду - у каждого своя правда и я с каждой по своему согласен smile.gif
Sergiy
Да кстати в продолжение темы, а знаете зачем у кварца при контроллерах с двух сторон кондерчики стоят, и почему для разных частот надо брать разную емкость (в пкФ), и не зависит ли от этой емкости частота конечная. Такой вопрос моему другу на беду задал залетный председатель комиссии на защите магистерской работы (нашел что у магистра спрашивать) smile.gif, ну вообщем парень конечно же не ответил, как в принципе и большая часть нашего профессорско-преподавательского состава smile.gif, а ответ то прост, но он нам просто не нужен в большинстве случаев, сказано надо ставить, значит надо ставить, начинаем думать только кода кто то раком запаял кандеры вместо пикофарад микрофарады или нанофарады, или еще какая то гадость, или как в этом случае хотим получить сумасшедшую точность измерения временных интервалов с таким вот кварцевым генератором, часть схемы которого реализован в дешевом микроконтроллере как Атмега8 (у нас он стоит чуть больше 1 евро), плюс ширпотребовский кварц на 1МГц, и сомнительные кондеры, хотя я обычно ставлю NPO, они очень стабильны во времени и температуры и там все нормально, но многие ставят X7R или X5R. Честь и хвала им (стоимость то одинаковая).
king2
И вот все равно не понимаю я...

Предположим, в этом примере добавили мы const1 в прерывании OVF1 и тут грянуло прерывание CAPT. Что получится?
smk
Цитата(GetSmart @ Jun 2 2006, 23:54) *
Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.


У меня ситуация, когда память Тини13 (1кь) заполнена на 960 байт, при этом ОЗУ 64 байт и его мало. Та-же прога, но адаптированная к Меге8 работает без проблем (512 байт ОЗУ). А TIFR один раз переполняется и сбросить его можно только принудительно записав в его единицу свою единицу (видать триггер там есть)! Просто присваиваем разряду 1 в дополнение к той, что там есть уже.
smk
Цитата(Sergiy @ Jun 4 2006, 00:14) *
частоту все таки надо повысить, чтобы хотя бы тут на элементарном не терять.

Кто не согласен со мной, спорить не буду - у каждого своя правда и я с каждой по своему согласен smile.gif


Уход в процентах не зависит от делителя. Вот уход в герцах!!! Это документируемо и полезно в плане утверждения документации. Иначе ваша погрешность - обнять и плакать! Вы поняли о чем я?
CD_Eater
Не пойму, к чему эти обсуждения наилучшего кода, если задачка поставлена некорректно.
Как уже было отмечено выше, точность 1 ppm на практике (используя типичный кварц) недостижима, поэтому увеличение разрядности счётчика таймера, применение однотактового аппаратного захвата и увеличение частота кварца никак не смогут улучшить ситуацию с относительной точностью измерения (которая в процентах).
А если МК тактирован частотой 1 МГц достаточной точности и имеет аппаратный захват, то задача решается даже на 8-битном таймере, используя только прерывание захвата. А если нужно экономить энергию спящим режимом, то придётся использовать прерывание захвата и прерывание переполнения таймера, причём не обязательно того же самого таймера, по которому производится захват.
khach
Как померять? Используя ГЛИН (генератор пилы) и внутренний АЦП АВРки. Внешней обвязки- два триггера и генератор тока на операционнике.
SasaVitebsk
Цитата(Sergiy @ Jun 4 2006, 00:14) *
все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.


smile.gif Вы сами поняли что вы написали???

А как вы узнали что "сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры" biggrin.gif

Это мне напоминает рассказ одного рыбака, который рассказывал следующее:

Ну бросаю пол-дня -- нифига. Ну потом нацепил наживку в виде лягушки и выбрасываю на берег. И медленно стягиваю в воду. smile.gif Понимаешь она (щука) стоит в воде и ждёт повернувшись мордой к берегу. А тут моя лягушка. biggrin.gif Ну и вытащил одну.


Короче приятно иметь знакомого, который запросто посмотрит внутрь процессора или сквозь толщу воды и заглянет в мозги щуки. А тут мозги подруги жизни (их там не много вроде), и то - сплошные потёмки. smile.gif
defunct
Цитата(smk @ Oct 5 2006, 19:30) *
У меня ситуация, когда память Тини13 (1кь) заполнена на 960 байт, при этом ОЗУ 64 байт и его мало. Та-же прога, но адаптированная к Меге8 работает без проблем (512 байт ОЗУ).

К чему бы это? Размер программы вообще роли не играет, а 64байта ОЗУ + столько же eeprom это на самом деле даже много c учетом, что программа на Asm.
Stanislav
Цитата(SasaVitebsk @ Oct 6 2006, 03:37) *
Цитата(Sergiy @ Jun 4 2006, 00:14) *

все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.


smile.gif Вы сами поняли что вы написали???
....................................
bb-offtopic.gif Дык, посмотрите, откуда парень пишет. У них там анашу на каждом углу продают вполне легально...
Прошу прощенья за оффтоп.
=GM=
Ну вот, опоздал к началу обсуждения, как всегда, впрочем(:-)
Цитата(AVR @ Jun 2 2006, 16:03) *
Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает...

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

Прежде всего, подключить измеряемый сигнал к схеме захвата, на таймер1 подать системный клок и выделить две 3-байтовые переменные, скажем, Т3-Т2-Т1 для хранения времени начала измеряемого интервала и Т6-Т5-Т4 для хранения времени конца интервала.

Затем надо написать программу со следующим алгоритмом.

1) Обнулить Т3 и Т6.

2) Стоять здесь и ждать первого захвата.

3) Переписать значение из регистра захвата в Т2-Т1.

4) Проверить наличие переноса из таймера1. При наличии переноса добавить единицу к Т6.

5) Проверить наличие второго захвата, если нет захвата перейти к п.4.

6) После захвата переписать значение из регистра захвата в Т5-Т4.

7) Вычислить разность двух переменных Т6-Т5-Т4 и Т3-Т2-Т1, которая даст длительность интервала в микросекундах, если системная частота равна 1 МГц. Выдать результат, куда надо.

8) Переписать Т6-Т5-Т4 в Т3-Т2-Т1.

9) Перейти к п.4.

Трёх байт должно хватить на длительности до 16 секунд, если надо больше, то взять 4-х байтные переменные и т.д. Относительная точность измерения будет определяться только погрешностью системной частоты +-1*Е-6.
_artem_
=GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков.
Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера

максимальная ошибка измерения будет равна произведению максимального количества инструкций выпоняемых в цикле подсчета времени и для получения заданной ошибки измерения , количество тактов на самую длинную операцию не должно превышать 16 при 16 МГц тактовой частоте при условии одномикросекундной погрешности
=GM=
Цитата(_artem_ @ Oct 6 2006, 16:17) *
=GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков.
Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера

максимальная ошибка измерения будет равна произведению максимального количества инструкций выпоняемых в цикле подсчета времени и для получения заданной ошибки измерения , количество тактов на самую длинную операцию не должно превышать 16 при 16 МГц тактовой частоте при условии одномикросекундной погрешности


Если честно, ничего не понял, что вы написали(:-(. Какое использование арифметических операций? Измерение делается на аппаратном уровне, от программы требуется только запомнить начальное и конечное время, учесть переносы таймера1, ну и вычислить разность времен, чтобы получить частоту.
_artem_
Правильно говорите - я то невнимательно прочитал подумал что поллингом считаете а флаги не в счет. Извиняюсь за ошибку. А даташит вообше то говорит Вашими словами .)

Можно и не анализировать флаги poll'om (правильно ли я понял?) а все делать в прерываниях, хотя для критического случая совпадения overflow с capture придется таки флаг overflow анализировать при исполнении прерывания в capture - overflow по приоритету ниже чем capture.
singlskv
Подправил немного код GetSmart и defunct
- добавил сохранение SREG в прерываниях
- добавил сброс флага TOV1 в TIFR если делали коррекцию

Код
.def  AL = R24
.def  Const0 = R8
.def  Const1 = R9
.def  _Sreg  = R10
....
    ldi   AL, 1
    mov   Const1, AL
    clr   Const0
...

; обработчик Input Capture:
TIM1_CAPT:
    in    _Sreg,SREG
    in    R4, ICR1L
    in    R5, ICR1H
    tst   R5
    brne  _do_not_correct_result
    in    AL, TIFR
    andi  AL, (1 << TOV1)
    breq  _do_not_correct_result
    out   TIFR, AL
    add   R2, Const1
    adc   R3, Const0
_do_not_correct_result:
    mov   R6, R2
    mov   R7, R3
    out   SREG,_Sreg
; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7)
    reti
    

; обработчик Timer Overflow:
TIM1_OVF:
    in    _Sreg,SREG
    add   R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика
    adc   R3, Const0; учет переноса.
    out   SREG,_Sreg
    reti
Stanislav
Цитата(=GM= @ Oct 6 2006, 20:22) *
Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные...
Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкС.
Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает.
=GM=
Цитата(Stanislav @ Oct 9 2006, 09:46) *
Цитата(=GM= @ Oct 6 2006, 20:22) *
Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные...
Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкс.
Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает.

Поясните, что в данном случае вы понимаете под погрешностью и разрешением? И как вы их вычисляете? Мне кажется, всем будет полезно понять разницу в понятиях.

На мой взгляд, погрешность метода (при наличии абсолютно точного генератора) составляет 1 мкс для секундного интервала при 1МГц системном клоке. Естественно, неточность генератора увеличивает погрешность. Хотя тут вопрос, может ли помочь тот факт, что кратковременная нестабильность (на секундном интервале) кварцевого генератора достигает 1Е-9..1Е-12?
GetSmart
Забавно. На этой странице всех повело совсем не в ту степь, о которой тема. Это как дайте кому-нить палец, дак он и всю руку оттяпает. Сам AVR пропал куда-то чтобы разъяснить, но в его вопросе нет слов о стабильности кварцев, а значит этот критерий точности не рассматривается. Есть слова о проце AVR и о 16 битном таймере. Если обращать внимание на них, то ответ уже давно дан положительный. Причём в условиях задачи это получается максимально возможная точность устройства, ну как 10-битный АЦП, у которого реальная точность всегда поменьше 10 бит из-за разных причин. То же и здесь. В силу разного времени прихода фронтов на шкале 1 мкс запросто может возникнуть "ошибка" вплоть до 1 мкс, от которой в данной схеме никак не избавиться. А вот всякие разговоры о точности и стабильности кварцев только дискредитируют авторов и вообще на мой взгляд какое-то балоболство.

=GM=
Причём тут кратковременная нестабильность в 1Е-9..1Е-12, если долговременная будет в 10000 раз хуже? Автоподстройки здесь нет и кратковременная нестабильность не спасает. А вообще, точность кварца при изготовлении наверно 1Е-4 и все разговоры о температурной и прочей нестабильности - бред какой-то.
=GM=
Цитата(singlskv @ Oct 7 2006, 09:37) *
Подправил немного код GetSmart и defunct
- добавил сохранение SREG в прерываниях
- добавил сброс флага TOV1 в TIFR если делали коррекцию

Код
.def  AL = R24
.def  Const0 = R8
.def  Const1 = R9
.def  _Sreg  = R10
....
    ldi   AL, 1
    mov   Const1, AL
    clr   Const0
...

; обработчик Input Capture:
TIM1_CAPT:
    in    _Sreg,SREG
    in    R4, ICR1L
    in    R5, ICR1H
    tst   R5
    brne  _do_not_correct_result
    in    AL, TIFR
    andi  AL, (1 << TOV1)
    breq  _do_not_correct_result
    out   TIFR, AL
    add   R2, Const1
    adc   R3, Const0
_do_not_correct_result:
    mov   R6, R2
    mov   R7, R3
    out   SREG,_Sreg
; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7)
    reti
    

; обработчик Timer Overflow:
TIM1_OVF:
    in    _Sreg,SREG
    add   R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика
    adc   R3, Const0; учет переноса.
    out   SREG,_Sreg
    reti


Хочу немного покритиковать программу.

1) От возникновения прерывания захвата до команды "in AL,TIFR" может пройти от 12 до 15 МЦ, т.е. достаточно много времени, чтобы произошел перенос от переполнения, следовательно, возможна ошибка в определении времени.

2) Вполне возможно, что если прерывания TIM1_OVF и TIM1_CAPT возникли в течение указанного периода, то прерывание TIM1_OVF выполнится после TIM1_CAPT и ПОВТОРНО скорректирует результат в r3-r2 (не уверен на все 100, надо проверять).

3) Вход в прерывание TIM1_CAPT означает конец интервала измерения и наличие правильного времени в r5-r4 за исключением возможного последнего переноса. Но поскольку перенос из r5-r4 в r7-r6 возможен в одном единственном случае, когда содержимое r5-r4 переходит из состояния 0xFFFF в 0x0000, содержимое регистров r5-r4 надо проверять на 0.

В соответствии со сказанным ниже приведена исправленная программа обработки.
Код
.def       temp   =r16
.def       savreg  =r10

; обработчик Input Capture:
TIM1_CAPT: in     savreg,SREG
           in     R4,ICR1L    ;точные два младших
           in     R5,ICR1H    ;байта времени
           movw   r6,r2       ;два старших байта времени
           mov    temp,r4     ;с возможным переносом
           or     temp,r5     ;во время захвата
           brne   nocarry     ;не было переноса
           subi   r6,-1       ;учтем
           sbci   r7,-1       ;перенос
nocarry:   out    SREG,Sreg
           reti

; обработчик Timer Overflow:
TIM1_OVF:  in     savreg,SREG
           subi   r2,-1       ;
           sbci   r3,-1       ;
           out    SREG,savreg
           reti


Ну и последнее, в подобных случаях предпочитаю использовать конструкцию
Код
           subi   r2,-1       ;
           sbci   r3,-1       ;

Вместо эквивалентной
Код
           add    R2,сonst1   ;
           adc    R3,сonst0   ;

что очевидно лучше, поскольку освобождаются два регистра сonst0 и сonst1.
GetSmart
Цитата(=GM=)
Код
           mov    temp,r4    ;с возможным переносом
           or     temp,r5    ;во время захвата
           brne   nocarry    ;не было переноса

Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT.
-----------
PS. У кого длиннее? smile.gif
=GM=
Цитата(GetSmart @ Oct 9 2006, 14:22) *
Цитата(=GM=)
Код
           mov    temp,r4;с возможным переносом
           or     temp,r5;во время захвата
           brne   nocarry;не было переноса

Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT.

Ничего не понял, поясните. Здесь никакой идеи, просто проверка содержимого r5:r4 на 0, только 0 может показать, что был перенос.
Stanislav
Цитата(=GM= @ Oct 9 2006, 16:56) *
Поясните, что в данном случае вы понимаете под погрешностью и разрешением? И как вы их вычисляете? Мне кажется, всем будет полезно понять разницу в понятиях.
Обратимся к посту №1 данной темы. Автор пишет:
Цитата
Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды?
Иными словами, опорный генератор не должен иметь отклонение частоты относительно мировых эталонов более 1/(N*1000000), где N -количество секунд в измеряемом интервале (шумы генератора здесь не рассматриваем). Получить такую точность с помощью простого генератора на кварце - сама по себе нетривиальная задача.
Когда же мы говорим о временнОм разрешении, то, как Вы верно заметили, под этим подразумевается погрешность метода. Она является абсолютной величиной, и не зависит от измеряемого интервала времени.
Суммарная ошибка в первом приближении определяется двумя этими факторами.

Цитата(=GM= @ Oct 9 2006, 16:56) *
Хотя тут вопрос, может ли помочь тот факт, что кратковременная нестабильность (на секундном интервале) кварцевого генератора достигает 1Е-9..1Е-12?
Нет, не поможет. Кратковременная нестабильность дополнительно ухудшает точность опорного генератора, хотя и является величиной "второго порядка малости". smile.gif
_artem_
Для микросекундной точности mожно скорректировать результат по секундным сигналам с gps.
Stanislav
Цитата(_artem_ @ Oct 9 2006, 20:11) *
Для микросекундной точности mожно скорректировать результат по секундным сигналам с gps.
Да, верно. Придётся делать контрольные замеры, можно даже с помощью того же таймера.
Только приемлемо ли это для автора темы?
GetSmart
Цитата(=GM=)
Ничего не понял, поясните. Здесь никакой идеи, просто проверка содержимого r5:r4 на 0, только 0 может показать, что был перенос.
Я же написал, что там может быть и 10 и 100 и при этом быть перенос. Что Вы не поняли? Что в системе может быть больше чем эти два прерывания? Вы хоть поняли как предыдущая версия программы работала?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.