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

 
 
> Точный подсчёт времени, как реализовать?
Leo_vrn
сообщение Aug 6 2006, 14:11
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 21-11-05
Из: Воронеж
Пользователь №: 11 151



Господа гуру в программировании AVR. Вопрос к вам.

Есть задачка точного измерения промежутков времени. Точность нужна до тысячной доли секунды. Подскажите, каким боком такое можно реализовать. Не должно быть погрешности измерения более 1 тысячной в интервале до 30 секунд.
В идеале нужна параллельная работа двух таких секундомеров. В принципе можно и по одному на разных кристаллах.
Выбор самого кристалла не очень важен. Главное, чтобы имел USART.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 26)
AVR
сообщение Aug 6 2006, 14:45
Сообщение #2


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(Leo_vrn @ Aug 6 2006, 18:11) *
Точность нужна до тысячной доли секунды. Подскажите, каким боком такое можно реализовать
Не уверен конечно, но возможно просто поставить таймер в режим сравнения и очистки по совпадению. В прерывании по совпадении таймера инкрементируется счетчик времени. В конце подсчета просто добавляется оставшееся в значение в счетчике таймера (с учетом того что на конец подсчета могло тоже произой прерывание по переполнению).


--------------------
Go to the top of the page
 
+Quote Post
junoSynthesizer
сообщение Aug 6 2006, 19:33
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397



я конечно не гуру а тоже нуб =), но кажись математику никто не отменял

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

т.е. заносим в счётчик цифру 6, чтобы прерывание было вызвано через 0,25 мс
после этого строим внешний счётчик четвертинок секунд (в теле прерывания)
таким образом мы получам погрешность половину от максимально допустимой (если с точностью до 1 мс, тогда максимальная 0,5 получается, вроде так)

и прикол в том, что таких таймеров можно запустить и 2 =)


--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
Go to the top of the page
 
+Quote Post
bodja74
сообщение Aug 6 2006, 20:45
Сообщение #4


Знающий
****

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



1 Инициализируем таймер Т1,если нужна точность ,или кварц с подходящим делителем или внешнее тактирование.
2 Указываем прерывание по захвату от Т1
3 В прерывании с регитра ICR читаем полученную длину импульса
4 Отправляем значение в USART

Пойдет мега8,16 и т.д.
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 6 2006, 21:03
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 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 и т.п.).
Go to the top of the page
 
+Quote Post
arttab
сообщение Aug 7 2006, 01:45
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



а если не серийка, то и поправочный коэфициетн для своего кварца измерить и корректировать измерения


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
Leo_vrn
сообщение Aug 7 2006, 07:49
Сообщение #7





Группа: Участник
Сообщений: 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 на другую ногу - останавливаем таймер.
Получается, что во времяцикла измерения контроллер должен будет постоянно опрашивать состояние одной из своих ног.
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение Aug 7 2006, 08:11
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 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. Чтобы начать новый цикл, нужно сбросить флаг готовности данных.

Точность такого метода плюс-минус период тактовой частоты, т.е. лучше микросекунды. И вычислительные ресурсы почти не тратятся.


--------------------
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 09:03
Сообщение #9


дятел
*****

Группа: Свой
Сообщений: 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 тактов.
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 09:45
Сообщение #10


кекс
******

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



Цитата(singlskv @ Aug 7 2006, 12:03) *
А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания
по переполнению ?

Где-то уже обсуждали подобный вопрос. GetSmart тогда предложил гениально простое решение - в обработчике "по захвату" просто проверять флаг переполнения из регистра TIFR.

Цитата(Леонид Иванович @ Aug 7 2006, 12:11) *
ИМХО если прерывания совпадут, то точность получится 65536 тактов.

См. выше ;>

Сообщение отредактировал defunct - Aug 7 2006, 09:45
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 10:50
Сообщение #11


дятел
*****

Группа: Свой
Сообщений: 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 тактов.
Go to the top of the page
 
+Quote Post
bodja74
сообщение Aug 7 2006, 11:44
Сообщение #12


Знающий
****

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



Цитата(singlskv @ Aug 7 2006, 12:03) *
А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания
по переполнению ?


Ничего страшного не произойдет,счетный регистр TCNT в момент захвата перенесет свое значение в регистр ICR и выставится флаг ICF регистра TIFR ,после окончания обработки прерывания по переполнению прога перейдет на прерывание по захвату.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 11:50
Сообщение #13


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(singlskv @ Aug 7 2006, 12:03) *
А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания
по переполнению ?

Я не очень точно там выразился, смотри мой последний пост.
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 11:56
Сообщение #14


кекс
******

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



Долго искал, но таки отыскал ветку где обсуждался подобный вопрос:

http://electronix.ru/forum/index.php?showtopic=16900&hl=

см. коментарий #8
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 12:13
Сообщение #15


дятел
*****

Группа: Свой
Сообщений: 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х тактовые команды в основном
цикле программы ?
Go to the top of the page
 
+Quote Post
bodja74
сообщение Aug 7 2006, 12:28
Сообщение #16


Знающий
****

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



Цитата(singlskv @ Aug 7 2006, 14:50) *
Цитата(singlskv @ Aug 7 2006, 12:03) *

А что мы посчитаем если прерывание по захвату выставит флаг в момент обработки прерывания
по переполнению ?

Я не очень точно там выразился, смотри мой последний пост.

Угу,в принципе не вижу смысла проверять ,пускай себе катится по прерыванию.
А лучше всего растянуть переполнение на более чем 30сек,как я уже писал - поставить
кварц типа 1.024Мгц,2.048Мгц, или внешний такт с той же тысячной и не мучатся со всем этим.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 12:46
Сообщение #17


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



ИМХО: при любой попытке "уточнить" значение измеряемого интервала
можно нарисовать временную диаграмму которая заставит ошибаться
алгоритм "уточнения".
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 12:54
Сообщение #18


кекс
******

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



Цитата(singlskv @ Aug 7 2006, 15:13) *
Цитата(defunct @ Jun 2 2006, 23:26) *

В таком виде как в примере - нельзя выполнять команды условного перехода и арифметические команды в основном цикле программы.

ну дык все правильно.
толко раскажите мне пожалуйста КАК не выполнять 2х/3х тактовые команды в основном
цикле программы ?

Речь там была не об этом. Абсолютно без разницы какой длины команды будут выполняться в основном цикле программы. Как видно из примера, в обработчиках прерываний у меня не сохраняется флаговый регистр SREG, соответственно арифметические операции и команды условных переходов в основном цикле программы могут выполняться некорректно.

Необходимо немного подправить пример - сохранять SREG на входе в обработчик прерываний и восстанавливать на выходе. А в остальном пример полностью рабочий.

PS: Также заметьте - тот пример был расчитан на обеспечение точности в 1mks, у Вас же речь идет о точности в 1ms (на три порядка меньше).

Сообщение отредактировал defunct - Aug 7 2006, 13:11
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 12:58
Сообщение #19


дятел
*****

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 13:22
Сообщение #20


дятел
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 14:49
Сообщение #21


кекс
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 15:32
Сообщение #22


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



smile.gif
Цитата(defunct @ Aug 7 2006, 18:49) *
singlskv

дык почитайте ветку дальше..

приведите пример кода и я Вам покажу пример когда Ваш код
будет работать неправильно smile.gif


Цитата(defunct @ Aug 7 2006, 18:49) *
singlskv

дык почитайте ветку дальше..

Цитата

переполнение" уже есть

В коде же специально есть проверка для этого случая.
Код
...
    mov   R7, R3
    tst   R5
    brne  _do_not_correct_result; <--- вот здесь принимается решение добавлять 0x10000 к результату или нет
...


просимулируйте Ваш код при R3:R2=5 b ICRH=FF ICRL=FD
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 16:01
Сообщение #23


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



2 defunct
кажется я понял откуда растут "уши" у нашего спора.
читаем datasheet:
When a capture is triggered, the
16-bit value of the counter (TCNT1) is written to the Input Capture Register (ICR1). The
Input Capture Flag (ICF1) is set at the same system clock as the TCNT1 value is copied
into ICR1 Register. If enabled (ICIE1 = 1), the Input Capture Flag generates an Input
Capture interrupt.
то есть значение таймера сохраняется в ICR ДО попадания в процедуру обработки
прерывания ICR, и любые попытки скоректировать значение счетчик могут привести
к ошибке.
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 16:10
Сообщение #24


кекс
******

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



Цитата(singlskv @ Aug 7 2006, 18:32) *
просимулируйте Ваш код при R3:R2=5 b ICRH=FF ICRL=FD

Запутали Вы меня.

Надо полагать раз Вы так уверено говорите о глюке и просите меня промоделировать работу примера, то Вы уже это проделали? В таком случае прошу сообщить результат.

Потому что код этот работает должным образом. И учитывает ту ситуацию, которую вы приводите в пример.

Сообщение отредактировал defunct - Aug 7 2006, 20:05
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 19:43
Сообщение #25


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Был неправ cranky.gif
tst r5
действительно решает проблемму,
только, чтобы все было коректно нужно после опроса "переполнения" в TIFR
сбрасывать флаг.
Go to the top of the page
 
+Quote Post
defunct
сообщение Aug 7 2006, 20:04
Сообщение #26


кекс
******

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



Цитата(singlskv @ Aug 7 2006, 22:43) *
только, чтобы все было коректно нужно после опроса "переполнения" в TIFR
сбрасывать флаг.

Согласен, спасибо!
Go to the top of the page
 
+Quote Post
singlskv
сообщение Aug 7 2006, 20:12
Сообщение #27


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ Aug 8 2006, 00:04) *
Цитата(singlskv @ Aug 7 2006, 22:43) *

только, чтобы все было коректно нужно после опроса "переполнения" в TIFR
сбрасывать флаг.

Согласен, спасибо!

И Вам спасибо!
мне почему-то показалось что это невозможно, но "tst r5" расставило все по местам...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 11:13
Рейтинг@Mail.ru


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