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

 
 
> Точный подсчёт времени, как реализовать?
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
 
Start new topic
Ответов
defunct
сообщение Aug 6 2006, 21:03
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 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
Leo_vrn
сообщение Aug 7 2006, 07:49
Сообщение #3





Группа: Участник
Сообщений: 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
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
Сообщение #5


дятел
*****

Группа: Свой
Сообщений: 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
bodja74
сообщение Aug 7 2006, 11:44
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 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
Сообщение #7


дятел
*****

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



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

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


Знающий
****

Группа: Свой
Сообщений: 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:58
Сообщение #9


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 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
Сообщение #12


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #13


дятел
*****

Группа: Свой
Сообщений: 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

Сообщений в этой теме
- 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
|- - 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


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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 14:10
Рейтинг@Mail.ru


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