|
|
  |
Измерение временных интервалов, с высокой точностью |
|
|
|
Oct 5 2006, 17:56
|
Частый гость
 
Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595

|
Не пойму, к чему эти обсуждения наилучшего кода, если задачка поставлена некорректно. Как уже было отмечено выше, точность 1 ppm на практике (используя типичный кварц) недостижима, поэтому увеличение разрядности счётчика таймера, применение однотактового аппаратного захвата и увеличение частота кварца никак не смогут улучшить ситуацию с относительной точностью измерения (которая в процентах). А если МК тактирован частотой 1 МГц достаточной точности и имеет аппаратный захват, то задача решается даже на 8-битном таймере, используя только прерывание захвата. А если нужно экономить энергию спящим режимом, то придётся использовать прерывание захвата и прерывание переполнения таймера, причём не обязательно того же самого таймера, по которому производится захват.
Сообщение отредактировал CD_Eater - Oct 5 2006, 18:00
|
|
|
|
|
Oct 5 2006, 23:37
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Sergiy @ Jun 4 2006, 00:14)  все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.  Вы сами поняли что вы написали??? А как вы узнали что "сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры" Это мне напоминает рассказ одного рыбака, который рассказывал следующее: Ну бросаю пол-дня -- нифига. Ну потом нацепил наживку в виде лягушки и выбрасываю на берег. И медленно стягиваю в воду.  Понимаешь она (щука) стоит в воде и ждёт повернувшись мордой к берегу. А тут моя лягушка.  Ну и вытащил одну. Короче приятно иметь знакомого, который запросто посмотрит внутрь процессора или сквозь толщу воды и заглянет в мозги щуки. А тут мозги подруги жизни (их там не много вроде), и то - сплошные потёмки.
|
|
|
|
|
Oct 6 2006, 11:58
|

Гуру
     
Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987

|
Цитата(SasaVitebsk @ Oct 6 2006, 03:37)  Цитата(Sergiy @ Jun 4 2006, 00:14)  все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.  Вы сами поняли что вы написали??? ....................................  Дык, посмотрите, откуда парень пишет. У них там анашу на каждом углу продают вполне легально... Прошу прощенья за оффтоп.
--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
|
|
|
|
|
Oct 6 2006, 16:22
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Ну вот, опоздал к началу обсуждения, как всегда, впрочем(:-) Цитата(AVR @ Jun 2 2006, 16:03)  Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает... Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные. По-моему, сделать надо вот что. Прежде всего, подключить измеряемый сигнал к схеме захвата, на таймер1 подать системный клок и выделить две 3-байтовые переменные, скажем, Т3-Т2-Т1 для хранения времени начала измеряемого интервала и Т6-Т5-Т4 для хранения времени конца интервала. Затем надо написать программу со следующим алгоритмом. 1) Обнулить Т3 и Т6. 2) Стоять здесь и ждать первого захвата. 3) Переписать значение из регистра захвата в Т2-Т1. 4) Проверить наличие переноса из таймера1. При наличии переноса добавить единицу к Т6. 5) Проверить наличие второго захвата, если нет захвата перейти к п.4. 6) После захвата переписать значение из регистра захвата в Т5-Т4. 7) Вычислить разность двух переменных Т6-Т5-Т4 и Т3-Т2-Т1, которая даст длительность интервала в микросекундах, если системная частота равна 1 МГц. Выдать результат, куда надо. 8) Переписать Т6-Т5-Т4 в Т3-Т2-Т1. 9) Перейти к п.4. Трёх байт должно хватить на длительности до 16 секунд, если надо больше, то взять 4-х байтные переменные и т.д. Относительная точность измерения будет определяться только погрешностью системной частоты +-1*Е-6.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 6 2006, 22:48
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(_artem_ @ Oct 6 2006, 16:17)  =GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков. Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера
максимальная ошибка измерения будет равна произведению максимального количества инструкций выпоняемых в цикле подсчета времени и для получения заданной ошибки измерения , количество тактов на самую длинную операцию не должно превышать 16 при 16 МГц тактовой частоте при условии одномикросекундной погрешности Если честно, ничего не понял, что вы написали(:-(. Какое использование арифметических операций? Измерение делается на аппаратном уровне, от программы требуется только запомнить начальное и конечное время, учесть переносы таймера1, ну и вычислить разность времен, чтобы получить частоту.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 7 2006, 10:37
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Подправил немного код GetSmart и defunct- добавил сохранение SREG в прерываниях - добавил сброс флага TOV1 в TIFR если делали коррекцию Код .def AL = R24 .def Const0 = R8 .def Const1 = R9 .def _Sreg = R10 .... ldi AL, 1 mov Const1, AL clr Const0 ...
; обработчик Input Capture: TIM1_CAPT: in _Sreg,SREG in R4, ICR1L in R5, ICR1H tst R5 brne _do_not_correct_result in AL, TIFR andi AL, (1 << TOV1) breq _do_not_correct_result out TIFR, AL add R2, Const1 adc R3, Const0 _do_not_correct_result: mov R6, R2 mov R7, R3 out SREG,_Sreg ; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7) reti
; обработчик Timer Overflow: TIM1_OVF: in _Sreg,SREG add R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика adc R3, Const0; учет переноса. out SREG,_Sreg reti
|
|
|
|
|
Oct 9 2006, 10:46
|

Гуру
     
Группа: Свой
Сообщений: 4 363
Регистрация: 13-05-05
Из: Москва
Пользователь №: 4 987

|
Цитата(=GM= @ Oct 6 2006, 20:22)  Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные... Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкС. Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает.
--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
|
|
|
|
|
Oct 9 2006, 12:56
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Stanislav @ Oct 9 2006, 09:46)  Цитата(=GM= @ Oct 6 2006, 20:22)  Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные... Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкс. Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает. Поясните, что в данном случае вы понимаете под погрешностью и разрешением? И как вы их вычисляете? Мне кажется, всем будет полезно понять разницу в понятиях. На мой взгляд, погрешность метода (при наличии абсолютно точного генератора) составляет 1 мкс для секундного интервала при 1МГц системном клоке. Естественно, неточность генератора увеличивает погрешность. Хотя тут вопрос, может ли помочь тот факт, что кратковременная нестабильность (на секундном интервале) кварцевого генератора достигает 1Е-9..1Е-12?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 9 2006, 13:35
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Забавно. На этой странице всех повело совсем не в ту степь, о которой тема. Это как дайте кому-нить палец, дак он и всю руку оттяпает. Сам AVR пропал куда-то чтобы разъяснить, но в его вопросе нет слов о стабильности кварцев, а значит этот критерий точности не рассматривается. Есть слова о проце AVR и о 16 битном таймере. Если обращать внимание на них, то ответ уже давно дан положительный. Причём в условиях задачи это получается максимально возможная точность устройства, ну как 10-битный АЦП, у которого реальная точность всегда поменьше 10 бит из-за разных причин. То же и здесь. В силу разного времени прихода фронтов на шкале 1 мкс запросто может возникнуть "ошибка" вплоть до 1 мкс, от которой в данной схеме никак не избавиться. А вот всякие разговоры о точности и стабильности кварцев только дискредитируют авторов и вообще на мой взгляд какое-то балоболство.
=GM= Причём тут кратковременная нестабильность в 1Е-9..1Е-12, если долговременная будет в 10000 раз хуже? Автоподстройки здесь нет и кратковременная нестабильность не спасает. А вообще, точность кварца при изготовлении наверно 1Е-4 и все разговоры о температурной и прочей нестабильности - бред какой-то.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Oct 9 2006, 13:59
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(singlskv @ Oct 7 2006, 09:37)  Подправил немного код GetSmart и defunct- добавил сохранение SREG в прерываниях - добавил сброс флага TOV1 в TIFR если делали коррекцию Код .def AL = R24 .def Const0 = R8 .def Const1 = R9 .def _Sreg = R10 .... ldi AL, 1 mov Const1, AL clr Const0 ...
; обработчик Input Capture: TIM1_CAPT: in _Sreg,SREG in R4, ICR1L in R5, ICR1H tst R5 brne _do_not_correct_result in AL, TIFR andi AL, (1 << TOV1) breq _do_not_correct_result out TIFR, AL add R2, Const1 adc R3, Const0 _do_not_correct_result: mov R6, R2 mov R7, R3 out SREG,_Sreg ; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7) reti
; обработчик Timer Overflow: TIM1_OVF: in _Sreg,SREG add R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика adc R3, Const0; учет переноса. out SREG,_Sreg reti Хочу немного покритиковать программу. 1) От возникновения прерывания захвата до команды "in AL,TIFR" может пройти от 12 до 15 МЦ, т.е. достаточно много времени, чтобы произошел перенос от переполнения, следовательно, возможна ошибка в определении времени. 2) Вполне возможно, что если прерывания TIM1_OVF и TIM1_CAPT возникли в течение указанного периода, то прерывание TIM1_OVF выполнится после TIM1_CAPT и ПОВТОРНО скорректирует результат в r3-r2 (не уверен на все 100, надо проверять). 3) Вход в прерывание TIM1_CAPT означает конец интервала измерения и наличие правильного времени в r5-r4 за исключением возможного последнего переноса. Но поскольку перенос из r5-r4 в r7-r6 возможен в одном единственном случае, когда содержимое r5-r4 переходит из состояния 0xFFFF в 0x0000, содержимое регистров r5-r4 надо проверять на 0. В соответствии со сказанным ниже приведена исправленная программа обработки. Код .def temp =r16 .def savreg =r10
; обработчик Input Capture: TIM1_CAPT: in savreg,SREG in R4,ICR1L ;точные два младших in R5,ICR1H ;байта времени movw r6,r2 ;два старших байта времени mov temp,r4 ;с возможным переносом or temp,r5 ;во время захвата brne nocarry ;не было переноса subi r6,-1 ;учтем sbci r7,-1 ;перенос nocarry: out SREG,Sreg reti
; обработчик Timer Overflow: TIM1_OVF: in savreg,SREG subi r2,-1 ; sbci r3,-1 ; out SREG,savreg reti Ну и последнее, в подобных случаях предпочитаю использовать конструкцию Код subi r2,-1 ; sbci r3,-1 ; Вместо эквивалентной Код add R2,сonst1 ; adc R3,сonst0 ; что очевидно лучше, поскольку освобождаются два регистра сonst0 и сonst1.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Oct 9 2006, 15:22
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(=GM=) Код mov temp,r4 ;с возможным переносом or temp,r5 ;во время захвата brne nocarry ;не было переноса Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT. ----------- PS. У кого длиннее?
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|