|
Точный подсчёт времени, как реализовать? |
|
|
|
Aug 6 2006, 14:11
|
Группа: Участник
Сообщений: 12
Регистрация: 21-11-05
Из: Воронеж
Пользователь №: 11 151

|
Господа гуру в программировании AVR. Вопрос к вам.
Есть задачка точного измерения промежутков времени. Точность нужна до тысячной доли секунды. Подскажите, каким боком такое можно реализовать. Не должно быть погрешности измерения более 1 тысячной в интервале до 30 секунд. В идеале нужна параллельная работа двух таких секундомеров. В принципе можно и по одному на разных кристаллах. Выбор самого кристалла не очень важен. Главное, чтобы имел USART.
|
|
|
|
|
Aug 6 2006, 19:33
|
Частый гость
 
Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397

|
я конечно не гуру а тоже нуб =), но кажись математику никто не отменял
недавно проверял внутренный clk атмеги на хорошем оборудовании - свой мегагерц у меня держала почти железно, следовательно, если нужна такая зверская точность, то мы можем без предварительного деления кинуть clk на таймер.
т.е. заносим в счётчик цифру 6, чтобы прерывание было вызвано через 0,25 мс после этого строим внешний счётчик четвертинок секунд (в теле прерывания) таким образом мы получам погрешность половину от максимально допустимой (если с точностью до 1 мс, тогда максимальная 0,5 получается, вроде так)
и прикол в том, что таких таймеров можно запустить и 2 =)
--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
|
|
|
|
|
Aug 6 2006, 21:03
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Leo_vrn @ Aug 6 2006, 17:11)  Есть задачка точного измерения промежутков времени. Точность нужна до тысячной доли секунды. Уточните задачу: Как и какие события будут сигнализировать МК о старте измерения и о финише? Потому что просто "отмерять" интервалы времени - тривиальная задача: зная возможности аппаратуры - 16 битный таймер в режиме CTC с генерацией прерывания, обеспечит абсолютно точное деление частоты осциллятора на любое натуральное число больше 11+(количество тактов требующихся на обработку). Дальше не составит труда преобразовать полученную таким образом частоту в интервал времени: T = OCR1X/ Fosc. Ну и подобрать осциллятор который обеспечит Вам требующуюся точность. Например пусть нужно точно отмерять интервал времени в 1ms, тогда, подставив этот интервал в формулу OCR1X = Fosc * 0.001c. для обеспечения высокой точности OCR1X должен быть натуральным числом >11, т.о. нам остается только подобрать кварц (любой из 4.000Mhz, 8.000Mhz, 10.000Mhz и т.п.).
|
|
|
|
|
Aug 7 2006, 07:49
|
Группа: Участник
Сообщений: 12
Регистрация: 21-11-05
Из: Воронеж
Пользователь №: 11 151

|
Цитата(defunct @ Aug 7 2006, 01:03)  Цитата(Leo_vrn @ Aug 6 2006, 17:11)  Есть задачка точного измерения промежутков времени. Точность нужна до тысячной доли секунды.
Уточните задачу: Как и какие события будут сигнализировать МК о старте измерения и о финише? Потому что просто "отмерять" интервалы времени - тривиальная задача: зная возможности аппаратуры - 16 битный таймер в режиме CTC с генерацией прерывания, обеспечит абсолютно точное деление частоты осциллятора на любое натуральное число больше 11+(количество тактов требующихся на обработку). Дальше не составит труда преобразовать полученную таким образом частоту в интервал времени: T = OCR1X/ Fosc. Ну и подобрать осциллятор который обеспечит Вам требующуюся точность. Например пусть нужно точно отмерять интервал времени в 1ms, тогда, подставив этот интервал в формулу OCR1X = Fosc * 0.001c. для обеспечения высокой точности OCR1X должен быть натуральным числом >11, т.о. нам остается только подобрать кварц (любой из 4.000Mhz, 8.000Mhz, 10.000Mhz и т.п.). В качестве события для старта и останова замера времени используется подача лог.0 на какую-нибудь ногу контроллера. То-есть пришёл 0 на одну ногу - запускаем таймер, пришёл 0 на другую ногу - останавливаем таймер. Получается, что во времяцикла измерения контроллер должен будет постоянно опрашивать состояние одной из своих ног.
|
|
|
|
|
Aug 7 2006, 08:11
|

Местный
  
Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986

|
Лучше всего использовать аппаратную схему захвата таймера. Только два разных сигнала СТАРТ и СТОП тогда нужно будет преобразовать в один импульс, длительность которого нужно измерить. Сделать это можно с помощью внешнего триггера. Этот импульс подаете на вход ICP1. Измеряем так:
1. Разрешаем прерывание по переполнению таймера 1. 2. Разрешаем прерывание по захвату таймера 1 при переходе из 0 в 1. 3. В обработчике прерывания по захвату, если сброшен флаг готовности данных, сохраняем значение регистра ICR1 в переменной A, очищаем переменную B, устанавливаем флаг начала измерения и перенастраиваем схему захвата на переход из 1 в 0. 4. В обработчике прерывания по переполнению таймера 1, если установлен флаг начала измерения, то считаем переполнения таймера в переменной B. 5. В обработчике прерывания по захвату, если установлен флаг начала измерения, сохраняем значение регистра ICR1 в переменной C, сбрасываем флаг начала измерения, устанавливаем флаг готовности данных.
Основная программа неспешно проверяет флаг готовности данных, когда он установится, делает вычисление интервала:
T = 65536 - A + 65536*B + C [периодов тактовой частоты]
Затем передает T по UART. Чтобы начать новый цикл, нужно сбросить флаг готовности данных.
Точность такого метода плюс-минус период тактовой частоты, т.е. лучше микросекунды. И вычислительные ресурсы почти не тратятся.
--------------------
|
|
|
|
|
Aug 7 2006, 09:03
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Леонид Иванович @ Aug 7 2006, 12:11)  Лучше всего использовать аппаратную схему захвата таймера. Только два разных сигнала СТАРТ и СТОП тогда нужно будет преобразовать в один импульс, длительность которого нужно измерить. Сделать это можно с помощью внешнего триггера. Этот импульс подаете на вход ICP1. Измеряем так:
1. Разрешаем прерывание по переполнению таймера 1. 2. Разрешаем прерывание по захвату таймера 1 при переходе из 0 в 1. 3. В обработчике прерывания по захвату, если сброшен флаг готовности данных, сохраняем значение регистра ICR1 в переменной A, очищаем переменную B, устанавливаем флаг начала измерения и перенастраиваем схему захвата на переход из 1 в 0. 4. В обработчике прерывания по переполнению таймера 1, если установлен флаг начала измерения, то считаем переполнения таймера в переменной B. А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания по переполнению ? Цитата(Леонид Иванович @ Aug 7 2006, 12:11)  Точность такого метода плюс-минус период тактовой частоты, т.е. лучше микросекунды. И вычислительные ресурсы почти не тратятся. ИМХО если прерывания совпадут, то точность получится 65536 тактов.
|
|
|
|
|
Aug 7 2006, 10:50
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Aug 7 2006, 13:45)  Где-то уже обсуждали подобный вопрос. GetSmart тогда предложил гениально простое решение - в обработчике "по захвату" просто проверять флаг переполнения из регистра TIFR. Код loop: rjmp loop; "захват" в середине 2х тактовой команды Вариант1 Вариант2 B=5 ICR=0000 B=5 ICR=FFFD в момент "захвата" "переполнение" нет "переполнения" ICR: ;обработчик прерывания "захват" "переполнение" "переполнения" проверка "переполнения" в TIFR inc B B=6 ICR=0000 B=6 ICR=FFFD ну вот мы и получили разницу >65000 тактов.
|
|
|
|
|
Aug 7 2006, 12:13
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Aug 7 2006, 15:56)  Долго искал, но таки отыскал ветку где обсуждался подобный вопрос: http://electronix.ru/forum/index.php?showtopic=16900&hl=см. коментарий #8 Цитата(defunct @ Jun 2 2006, 23:26)  В таком виде как в примере - нельзя выполнять команды условного перехода и арифметические команды в основном цикле программы. ну дык все правильно. толко раскажите мне пожалуйста КАК не выполнять 2х/3х тактовые команды в основном цикле программы ?
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|