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

 
 
> Точный подсчёт времени, как реализовать?
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

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


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 00:03
Рейтинг@Mail.ru


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