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

|
Господа гуру в программировании AVR. Вопрос к вам.
Есть задачка точного измерения промежутков времени. Точность нужна до тысячной доли секунды. Подскажите, каким боком такое можно реализовать. Не должно быть погрешности измерения более 1 тысячной в интервале до 30 секунд. В идеале нужна параллельная работа двух таких секундомеров. В принципе можно и по одному на разных кристаллах. Выбор самого кристалла не очень важен. Главное, чтобы имел USART.
|
|
|
|
|
 |
Ответов
|
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, 12:28
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(singlskv @ Aug 7 2006, 14:50)  Цитата(singlskv @ Aug 7 2006, 12:03)  А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания по переполнению ?
Я не очень точно там выразился, смотри мой последний пост. Угу,в принципе не вижу смысла проверять ,пускай себе катится по прерыванию. А лучше всего растянуть переполнение на более чем 30сек,как я уже писал - поставить кварц типа 1.024Мгц,2.048Мгц, или внешний такт с той же тысячной и не мучатся со всем этим.
|
|
|
|
|
Aug 7 2006, 12:58
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(bodja74 @ Aug 7 2006, 16:28)  Угу,в принципе не вижу смысла проверять ,пускай себе катится по прерыванию. А лучше всего растянуть переполнение на более чем 30сек,как я уже писал - поставить кварц типа 1.024Мгц,2.048Мгц, или внешний такт с той же тысячной и не мучатся со всем этим. Ну, да это единственный метод, если нужна "абсолютная" точность. Можно даже выбрать кварц 4,096 или 8,192 , но на время измерения запрограммировать CLKPR на деление на 2,4 или 8, а делитель таймера на 1024. Ну или просто режим CTC с прерыванием каждую ms, но при этом придется забить на то что результаты отличающиеся на несколько мкс могут в итоге отличаться на 1 ms.
|
|
|
|
|
Aug 7 2006, 13:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Jun 2 2006, 23:26)  Код .def AL = R24 .def Const0 = R8 .def Const1 = R9
.... ldi AL, 1 mov Const1, AL clr Const0 ...
loop:
rjmp loop ; B=5 ICR=FFFD "захват" здесь "переполнения" еще нет
; обработчик 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
|
|
|
|
|
Aug 7 2006, 14:49
|

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

|
singlskvдык почитайте ветку дальше.. Цитата переполнение" уже есть В коде же специально есть проверка для этого случая. Код ... mov R7, R3 tst R5 brne _do_not_correct_result ; <--- вот здесь принимается решение добавлять 0x10000 к результату или нет ...
Сообщение отредактировал defunct - Aug 7 2006, 15:20
|
|
|
|
Сообщений в этой теме
Leo_vrn Точный подсчёт времени Aug 6 2006, 14:11 AVR Цитата(Leo_vrn @ Aug 6 2006, 18:11) Точно... Aug 6 2006, 14:45 junoSynthesizer я конечно не гуру а тоже нуб =), но кажись математ... Aug 6 2006, 19:33 bodja74 1 Инициализируем таймер Т1,если нужна точность ,ил... Aug 6 2006, 20:45    defunct Цитата(singlskv @ Aug 7 2006, 12:03) А чт... Aug 7 2006, 09:45     singlskv Цитата(defunct @ Aug 7 2006, 13:45) Где-т... Aug 7 2006, 10:50          singlskv Цитата(defunct @ Aug 7 2006, 18:49) singl... Aug 7 2006, 15:32           singlskv 2 defunct
кажется я понял откуда растут "уши... Aug 7 2006, 16:01           defunct Цитата(singlskv @ Aug 7 2006, 18:32) прос... Aug 7 2006, 16:10            singlskv Был неправ
tst r5
действительно решает проблем... Aug 7 2006, 19:43             defunct Цитата(singlskv @ Aug 7 2006, 22:43) толь... Aug 7 2006, 20:04              singlskv Цитата(defunct @ Aug 8 2006, 00:04) Цитат... Aug 7 2006, 20:12 arttab а если не серийка, то и поправочный коэфициетн для... Aug 7 2006, 01:45 defunct Долго искал, но таки отыскал ветку где обсуждался ... Aug 7 2006, 11:56 singlskv Цитата(defunct @ Aug 7 2006, 15:56) Долго... Aug 7 2006, 12:13  singlskv ИМХО: при любой попытке "уточнить" значе... Aug 7 2006, 12:46  defunct Цитата(singlskv @ Aug 7 2006, 15:13) Цита... Aug 7 2006, 12:54
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|