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

 
 
> Измерение временных интервалов, с высокой точностью
AVR
сообщение Jun 2 2006, 17:03
Сообщение #1


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

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



Здравствуйте!
Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает...


--------------------
Go to the top of the page
 
+Quote Post
9 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 99)
WHALE
сообщение Jun 2 2006, 17:07
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



C точностью до микросекунды с кварцем на 1Мгц никак.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 17:10
Сообщение #3


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 2 2006, 17:20
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(GetSmart @ Jun 2 2006, 23:10) *
А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?

А считывать значения периода с разрешением 1мкс при тактовой 1МГц он будет успевать? smile.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 17:23
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
C точностью до микросекунды с кварцем на 1Мгц никак.

А я бы сказал - элементарно, но на AVR. Для PIC не знаю точно, есть у них функция захвата и есть ли делитель у таймера? То есть инкрементируется таймер от 1 МГц или от делителя 1/4 или ещё как. Если от 1 МГц и есть захват, то этого достаточно. Ну и интервал не должен быть очень маленьким. Внутри него должно успеть обработаться прерывание.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
AVR
сообщение Jun 2 2006, 17:24
Сообщение #6


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

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



Цитата(GetSmart @ Jun 2 2006, 21:10) *
А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?
Можно подробнее чуточку? Какие старшие 16 бит? Подскажите, пожалуйста, как это можно сделать?
Я пытался реализовать это так:
По внешнему прерыванию ставлю таймер в режим сравнения на 50К (+обнуление по переполнению) и по прерыванию увеличиваю значение 32-битной переменной в ОЗУ на эти самые 50к. После ещё одного внешнего прерывания останавливаю таймер и остаток (содержимое TCNTn) добавляю к этой же переменной (после чего обнуляю TCNTn). Но: в результате, хоть я и подаю на вход импульсы постоянной длительности, значения на выходе пляшут как будет бы у меня генератор случайных чисел =(

Сообщение отредактировал AVR - Jun 2 2006, 17:33


--------------------
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 17:43
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Чё-то я ослеп. Речь как раз об AVR. Берёте Мегу8, она с захватом. Всё получится с точностью 1 мкс, если интервалы будут хотя бы 10 и более мкс. Это если писать на асме. Если на си, то раза в 3 большие интервалы.

Вроде бы правильно делаете. Может какая мелкая ошибка. Прикрепите исходник, я посмотрю. Кстати, когда обнуляете таймер, обнуляете ещё переменную?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2006, 19:26
Сообщение #8


кекс
******

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



Цитата(GetSmart @ Jun 2 2006, 20:43) *
Чё-то я ослеп. Речь как раз об AVR. Берёте Мегу8, она с захватом. Всё получится с точностью 1 мкс, если интервалы будут хотя бы 10 и более мкс. Это если писать на асме. Если на си, то раза в 3 большие интервалы.

Вроде бы правильно делаете. Может какая мелкая ошибка. Прикрепите исходник, я посмотрю. Кстати, когда обнуляете таймер, обнуляете ещё переменную?


Получится, но с одной оговоркой:

не всегда будет указанная точность.

Нельзя выйти на точность в 1мкс в случае когда прерывание таймера "по захвату" сработает одновременно с прерыванием таймера "по переполнению" либо по "сравнению" для увеличения старшей части 32-х битного счетчика времени.


Цитата
Можно подробнее чуточку? Какие старшие 16 бит? Подскажите, пожалуйста, как это можно сделать?

Пример, с учетом того, что Timer1 уже настроен на работу в режиме Input Capture с генерацией прерываний по CAPT и по OVF.
В таком виде как в примере - нельзя выполнять команды условного перехода и арифметические команды в основном цикле программы.


Код
.def  AL = R24
.def  Const0 = R8
.def  Const1 = R9

....
   ldi  AL, 1
   mov  Const1, AL
   clr  Const0
...

; обработчик 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
GetSmart
сообщение Jun 2 2006, 19:51
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
Нельзя выйти на точность в 1мкс в случае когда прерывание таймера "по захвату" сработает одновременно с прерыванием таймера "по переполнению" либо по "сравнению" для увеличения старшей части 32-х битного счетчика времени.

Ну почему же? Захват же аппаратный. Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению. А если захват аппаратный и прерывание по переполнению, то таймер никогда не останавливается и "захватывается" точное значение. Поэтому я бы рекомендовал делать прерывание именно по переполнению.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2006, 20:32
Сообщение #10


кекс
******

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



Цитата(GetSmart @ Jun 2 2006, 22:51) *
Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению.

Да все так, доп проверка для ((ICR > 0) и (ICR < длительность обработчика OVF))
Все равно есть ситуации где точность 1mks на двух прерываниях обеспечить не реально.
Ну представьте захвачен ICR = 0.
Что делать? Было отработано прерывание по переполнению или нет? А бог его знает. Если CAPT сработал в момент перехода на обработку OVF - то было, если раньше - то не было. А теряется не много ни мало всего лишь 64k mks ;>

т.е. думаю нужно вводить еще прерывание OC, с OCR = 64k/2, чтобы точно знать о природе ICR=0.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 20:54
Сообщение #11


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2006, 20:57
Сообщение #12


кекс
******

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



Цитата(GetSmart @ Jun 2 2006, 23:54) *
Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.

Действительно a14.gif
"А ларчик то просто открывался" smile.gif

(подправил код примера с учетом Вашего последнего поста.)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 21:18
Сообщение #13


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2006, 21:45
Сообщение #14


кекс
******

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



Цитата(GetSmart @ Jun 3 2006, 00:18) *
Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить.

Там это учтено:

tst r1
brne ...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 21:53
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
Там это учтено:

Да, я это написал когда ещё не было.

Кстати, 16 бит таймера и 8 старших бит счётчика в регистре дадут уже период в 16 секунд. Может этого будет достаточно?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 2 2006, 22:05
Сообщение #16


кекс
******

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



Цитата(GetSmart @ Jun 3 2006, 00:53) *
Кстати, 16 бит таймера и 8 старших бит счётчика в регистре дадут уже период в 16 секунд. Может этого будет достаточно?


Немного изменил код, счетчик не сбрасывается, а постоянно накапливается. Результатом измерения будет разность между двумя захватами. А в такой реализации 8 бит может быть недостаточно.
Таймер (TCNT) конечно можно корректировать в обработчике CAPT, но это IMHO будет некрасивое решение.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 2 2006, 23:02
Сообщение #17


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Вроде нормальный пример. Тока непонятно зачем R0 и R1 используются.

Кстати, то что прерывание захвата приоритетней переполнения это хорошо. Иначе гемору было бы больше.


Хотя... постойте... В прерывании OVR инкрементируются R3:R2, которые потом копируются в R7:R6. Однако при отложенном прерывании OVR почему-то у Вас инкрементируется не R7:R6, а R4 и далее по списку.

Сообщение отредактировал GetSmart - Jun 2 2006, 23:08


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 3 2006, 05:22
Сообщение #18


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



???


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 3 2006, 06:28
Сообщение #19


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



О чем вы, господа? Забыли, что внутри проца есть еще синхронизация пина? т.е. 1-2 такта задержки вам обеспечено.. Что больше необходимой 1мкс (при тактовой 1МГц).


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 3 2006, 06:53
Сообщение #20


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



О чём вы, господин? Задержка всегда постоянная. И для двух фронтов она компенсирует друг друга.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 3 2006, 07:20
Сообщение #21


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Э, да, вспылил, был неправ wink.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 3 2006, 13:02
Сообщение #22


кекс
******

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



Цитата(GetSmart @ Jun 3 2006, 02:02) *
Хотя... постойте... В прерывании OVR инкрементируются R3:R2, которые потом копируются в R7:R6. Однако при отложенном прерывании OVR почему-то у Вас инкрементируется не R7:R6, а R4 и далее по списку.

Ой.. и правда.
Успел отредактировать ;>
Go to the top of the page
 
+Quote Post
Валентиныч
сообщение Jun 3 2006, 14:17
Сообщение #23


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

Группа: Свой
Сообщений: 553
Регистрация: 17-02-05
Из: Свердловская обл.
Пользователь №: 2 712



А чем вызвано ограничение по кварцу - 1 МГц? (Или я проглядел?)
При расширении разрядности таймера до 24-32 разрядов (да хоть до 64-х! biggrin.gif ) увеличение тактовой до 8-16 МГц резко увеличит точность при сокращении времени измерения.


--------------------
Закономерность: Чем больше узнаю, тем меньше знаю...
Любые мнения, даже ошибочные, имеют право на существование.
Чем лучше узнаю людей, тем больше нравятся собаки...
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 3 2006, 17:16
Сообщение #24


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



defunct
Ну ёкарный бабай...
Ещё нужно заменить "tst R1; brne ..." на "tst R5; brmi ..."
Поясню почему. Дело в том, такая конструкция допускает ещё другие, длительные прерывания (до 32к тактов). При этом конечно периоды импульсов должны быть ещё больше. Вобщем мне кажется, что так более логично и идеальнее алгоритм.

Не понимаю как Вам удаётся менять посты без надписи "отредактировано"?!


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 3 2006, 19:05
Сообщение #25


кекс
******

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



Цитата(GetSmart @ Jun 3 2006, 20:16) *
defunct
Ну ёкарный бабай...
Ещё нужно заменить "tst R1; brne ..." на "tst R5; brmi ..."
Поясню почему. Дело в том, такая конструкция допускает ещё другие, длительные прерывания (до 32к тактов). При этом конечно периоды импульсов должны быть ещё больше. Вобщем мне кажется, что так более логично и идеальнее алгоритм.

R1 на R5 заменил!
Насчет brmi - на любителя, но я все же предпочитаю brne. 256 тактов и так предостаточно. Все таки задача мерять интервалы времени с точностью 1mks, а не принимать антикризисные меры по оживлению программы с курса ...123 в котором задержка в обработчике прерывания на 20ms считается нормальным явлением. Длительные прерывания - от лукавого, никогда такого не делаю и никому не советую.

Цитата
Не понимаю как Вам удаётся менять посты без надписи "отредактировано"?!

Полная правка?

ps: извиняюсь за мою невнимательность и небрежность при написании примера. GetSmart пожалуйста, если там еще что-то заметите, просто внесите Ваши исправления и запостите отдельным сообщением. (а то как-то неудобно уже постить на эту тему и бесконечно править 10 строчек кода) smile.gif
Go to the top of the page
 
+Quote Post
Sergiy
сообщение Jun 3 2006, 21:14
Сообщение #26


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 29-05-06
Из: Netherlands (Delft)/Ukraine (Odessa)
Пользователь №: 17 547



все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.

Да, еще раз задам вопрос, почему выбрана частота - 1МГц, может парень просто хочет пользовать калиброванную RC-цепочку в качестве задатчика частоты smile.gif.

Надо понимать что даже кварц, как эталон до какой то степени, имеет свою погрешность начальную (отличается от партии к партии), температурный дрейф (уход в температуре), временной дрейф или стабильность (уход за 1000ч нормирован). И много еще источников погрешности уже в самом начале.

Так вот парень хочет мерять интервалы времени в секунды (единицы например) при точности в 1мкс, если я правильно понял, имеем на лицо требуемую точность менее 1ppm. Теперь открываем паспортные данные на самые лучшие кварцы ширпотреба или даже проф. Ну что поняли мысль или нет. Ну если мы возмем эталоны частоты (времени) на радиоизотопах, термостабилизированные, состаренные и так далее - ну тогда мы будем говорить, но знаете скока стоит такая каробочка. Может все таки надо пересмотреть точность. Или сказать что девайс будет использоваться в очень узком температурном диапазоне, и к этому будет калиброваться раз в месяц эталонном. Тогда можно говорить о реализации программы в АВР, хотя я бы сказал, что частоту все таки надо повысить, чтобы хотя бы тут на элементарном не терять.

Кто не согласен со мной, спорить не буду - у каждого своя правда и я с каждой по своему согласен smile.gif
Go to the top of the page
 
+Quote Post
Sergiy
сообщение Jun 3 2006, 21:29
Сообщение #27


Участник
*

Группа: Новичок
Сообщений: 26
Регистрация: 29-05-06
Из: Netherlands (Delft)/Ukraine (Odessa)
Пользователь №: 17 547



Да кстати в продолжение темы, а знаете зачем у кварца при контроллерах с двух сторон кондерчики стоят, и почему для разных частот надо брать разную емкость (в пкФ), и не зависит ли от этой емкости частота конечная. Такой вопрос моему другу на беду задал залетный председатель комиссии на защите магистерской работы (нашел что у магистра спрашивать) smile.gif, ну вообщем парень конечно же не ответил, как в принципе и большая часть нашего профессорско-преподавательского состава smile.gif, а ответ то прост, но он нам просто не нужен в большинстве случаев, сказано надо ставить, значит надо ставить, начинаем думать только кода кто то раком запаял кандеры вместо пикофарад микрофарады или нанофарады, или еще какая то гадость, или как в этом случае хотим получить сумасшедшую точность измерения временных интервалов с таким вот кварцевым генератором, часть схемы которого реализован в дешевом микроконтроллере как Атмега8 (у нас он стоит чуть больше 1 евро), плюс ширпотребовский кварц на 1МГц, и сомнительные кондеры, хотя я обычно ставлю NPO, они очень стабильны во времени и температуры и там все нормально, но многие ставят X7R или X5R. Честь и хвала им (стоимость то одинаковая).
Go to the top of the page
 
+Quote Post
king2
сообщение Oct 5 2006, 01:30
Сообщение #28


Местный
***

Группа: Свой
Сообщений: 255
Регистрация: 17-08-06
Из: Москва
Пользователь №: 19 646



И вот все равно не понимаю я...

Предположим, в этом примере добавили мы const1 в прерывании OVF1 и тут грянуло прерывание CAPT. Что получится?
Go to the top of the page
 
+Quote Post
smk
сообщение Oct 5 2006, 16:30
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(GetSmart @ Jun 2 2006, 23:54) *
Цитата
Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет?

Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет.


У меня ситуация, когда память Тини13 (1кь) заполнена на 960 байт, при этом ОЗУ 64 байт и его мало. Та-же прога, но адаптированная к Меге8 работает без проблем (512 байт ОЗУ). А TIFR один раз переполняется и сбросить его можно только принудительно записав в его единицу свою единицу (видать триггер там есть)! Просто присваиваем разряду 1 в дополнение к той, что там есть уже.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Oct 5 2006, 17:02
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(Sergiy @ Jun 4 2006, 00:14) *
частоту все таки надо повысить, чтобы хотя бы тут на элементарном не терять.

Кто не согласен со мной, спорить не буду - у каждого своя правда и я с каждой по своему согласен smile.gif


Уход в процентах не зависит от делителя. Вот уход в герцах!!! Это документируемо и полезно в плане утверждения документации. Иначе ваша погрешность - обнять и плакать! Вы поняли о чем я?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
CD_Eater
сообщение Oct 5 2006, 17:56
Сообщение #31


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

Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595



Не пойму, к чему эти обсуждения наилучшего кода, если задачка поставлена некорректно.
Как уже было отмечено выше, точность 1 ppm на практике (используя типичный кварц) недостижима, поэтому увеличение разрядности счётчика таймера, применение однотактового аппаратного захвата и увеличение частота кварца никак не смогут улучшить ситуацию с относительной точностью измерения (которая в процентах).
А если МК тактирован частотой 1 МГц достаточной точности и имеет аппаратный захват, то задача решается даже на 8-битном таймере, используя только прерывание захвата. А если нужно экономить энергию спящим режимом, то придётся использовать прерывание захвата и прерывание переполнения таймера, причём не обязательно того же самого таймера, по которому производится захват.

Сообщение отредактировал CD_Eater - Oct 5 2006, 18:00
Go to the top of the page
 
+Quote Post
khach
сообщение Oct 5 2006, 19:49
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 3 439
Регистрация: 29-12-04
Пользователь №: 1 741



Как померять? Используя ГЛИН (генератор пилы) и внутренний АЦП АВРки. Внешней обвязки- два триггера и генератор тока на операционнике.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 5 2006, 23:37
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Sergiy @ Jun 4 2006, 00:14) *
все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.


smile.gif Вы сами поняли что вы написали???

А как вы узнали что "сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры" biggrin.gif

Это мне напоминает рассказ одного рыбака, который рассказывал следующее:

Ну бросаю пол-дня -- нифига. Ну потом нацепил наживку в виде лягушки и выбрасываю на берег. И медленно стягиваю в воду. smile.gif Понимаешь она (щука) стоит в воде и ждёт повернувшись мордой к берегу. А тут моя лягушка. biggrin.gif Ну и вытащил одну.


Короче приятно иметь знакомого, который запросто посмотрит внутрь процессора или сквозь толщу воды и заглянет в мозги щуки. А тут мозги подруги жизни (их там не много вроде), и то - сплошные потёмки. smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 6 2006, 11:11
Сообщение #34


кекс
******

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



Цитата(smk @ Oct 5 2006, 19:30) *
У меня ситуация, когда память Тини13 (1кь) заполнена на 960 байт, при этом ОЗУ 64 байт и его мало. Та-же прога, но адаптированная к Меге8 работает без проблем (512 байт ОЗУ).

К чему бы это? Размер программы вообще роли не играет, а 64байта ОЗУ + столько же eeprom это на самом деле даже много c учетом, что программа на Asm.
Go to the top of the page
 
+Quote Post
Stanislav
сообщение Oct 6 2006, 11:58
Сообщение #35


Гуру
******

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



Цитата(SasaVitebsk @ Oct 6 2006, 03:37) *
Цитата(Sergiy @ Jun 4 2006, 00:14) *

все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры.


smile.gif Вы сами поняли что вы написали???
....................................
bb-offtopic.gif Дык, посмотрите, откуда парень пишет. У них там анашу на каждом углу продают вполне легально...
Прошу прощенья за оффтоп.


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 6 2006, 16:22
Сообщение #36


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.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
_artem_
сообщение Oct 6 2006, 17:17
Сообщение #37


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



=GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков.
Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера

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


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 6 2006, 22:48
Сообщение #38


Ambidexter
*****

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



Цитата(_artem_ @ Oct 6 2006, 16:17) *
=GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков.
Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера

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


Если честно, ничего не понял, что вы написали(:-(. Какое использование арифметических операций? Измерение делается на аппаратном уровне, от программы требуется только запомнить начальное и конечное время, учесть переносы таймера1, ну и вычислить разность времен, чтобы получить частоту.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
_artem_
сообщение Oct 7 2006, 00:10
Сообщение #39


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Правильно говорите - я то невнимательно прочитал подумал что поллингом считаете а флаги не в счет. Извиняюсь за ошибку. А даташит вообше то говорит Вашими словами .)

Можно и не анализировать флаги poll'om (правильно ли я понял?) а все делать в прерываниях, хотя для критического случая совпадения overflow с capture придется таки флаг overflow анализировать при исполнении прерывания в capture - overflow по приоритету ниже чем capture.


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 7 2006, 10:37
Сообщение #40


дятел
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Stanislav
сообщение Oct 9 2006, 10:46
Сообщение #41


Гуру
******

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



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


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 9 2006, 12:56
Сообщение #42


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?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 9 2006, 13:35
Сообщение #43


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Забавно. На этой странице всех повело совсем не в ту степь, о которой тема. Это как дайте кому-нить палец, дак он и всю руку оттяпает. Сам AVR пропал куда-то чтобы разъяснить, но в его вопросе нет слов о стабильности кварцев, а значит этот критерий точности не рассматривается. Есть слова о проце AVR и о 16 битном таймере. Если обращать внимание на них, то ответ уже давно дан положительный. Причём в условиях задачи это получается максимально возможная точность устройства, ну как 10-битный АЦП, у которого реальная точность всегда поменьше 10 бит из-за разных причин. То же и здесь. В силу разного времени прихода фронтов на шкале 1 мкс запросто может возникнуть "ошибка" вплоть до 1 мкс, от которой в данной схеме никак не избавиться. А вот всякие разговоры о точности и стабильности кварцев только дискредитируют авторов и вообще на мой взгляд какое-то балоболство.

=GM=
Причём тут кратковременная нестабильность в 1Е-9..1Е-12, если долговременная будет в 10000 раз хуже? Автоподстройки здесь нет и кратковременная нестабильность не спасает. А вообще, точность кварца при изготовлении наверно 1Е-4 и все разговоры о температурной и прочей нестабильности - бред какой-то.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 9 2006, 13:59
Сообщение #44


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.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 9 2006, 15:22
Сообщение #45


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Код
           mov    temp,r4    ;с возможным переносом
           or     temp,r5    ;во время захвата
           brne   nocarry    ;не было переноса

Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT.
-----------
PS. У кого длиннее? smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 9 2006, 16:06
Сообщение #46


Ambidexter
*****

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



Цитата(GetSmart @ Oct 9 2006, 14:22) *
Цитата(=GM=)
Код
           mov    temp,r4;с возможным переносом
           or     temp,r5;во время захвата
           brne   nocarry;не было переноса

Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT.

Ничего не понял, поясните. Здесь никакой идеи, просто проверка содержимого r5:r4 на 0, только 0 может показать, что был перенос.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Stanislav
сообщение Oct 9 2006, 16:09
Сообщение #47


Гуру
******

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



Цитата(=GM= @ Oct 9 2006, 16:56) *
Поясните, что в данном случае вы понимаете под погрешностью и разрешением? И как вы их вычисляете? Мне кажется, всем будет полезно понять разницу в понятиях.
Обратимся к посту №1 данной темы. Автор пишет:
Цитата
Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды?
Иными словами, опорный генератор не должен иметь отклонение частоты относительно мировых эталонов более 1/(N*1000000), где N -количество секунд в измеряемом интервале (шумы генератора здесь не рассматриваем). Получить такую точность с помощью простого генератора на кварце - сама по себе нетривиальная задача.
Когда же мы говорим о временнОм разрешении, то, как Вы верно заметили, под этим подразумевается погрешность метода. Она является абсолютной величиной, и не зависит от измеряемого интервала времени.
Суммарная ошибка в первом приближении определяется двумя этими факторами.

Цитата(=GM= @ Oct 9 2006, 16:56) *
Хотя тут вопрос, может ли помочь тот факт, что кратковременная нестабильность (на секундном интервале) кварцевого генератора достигает 1Е-9..1Е-12?
Нет, не поможет. Кратковременная нестабильность дополнительно ухудшает точность опорного генератора, хотя и является величиной "второго порядка малости". smile.gif


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
_artem_
сообщение Oct 9 2006, 16:11
Сообщение #48


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Для микросекундной точности mожно скорректировать результат по секундным сигналам с gps.


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
Stanislav
сообщение Oct 9 2006, 16:13
Сообщение #49


Гуру
******

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



Цитата(_artem_ @ Oct 9 2006, 20:11) *
Для микросекундной точности mожно скорректировать результат по секундным сигналам с gps.
Да, верно. Придётся делать контрольные замеры, можно даже с помощью того же таймера.
Только приемлемо ли это для автора темы?


--------------------
Самонадеянность слепа. Сомнения - спутник разума. (с)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 9 2006, 16:24
Сообщение #50


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Ничего не понял, поясните. Здесь никакой идеи, просто проверка содержимого r5:r4 на 0, только 0 может показать, что был перенос.
Я же написал, что там может быть и 10 и 100 и при этом быть перенос. Что Вы не поняли? Что в системе может быть больше чем эти два прерывания? Вы хоть поняли как предыдущая версия программы работала?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 9 2006, 16:34
Сообщение #51


дятел
*****

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



Цитата(=GM= @ Oct 9 2006, 17:59) *
Хочу немного покритиковать программу.

1) От возникновения прерывания захвата до команды "in AL,TIFR" может пройти от 12 до 15 МЦ, т.е. достаточно много времени, чтобы произошел перенос от переполнения, следовательно, возможна ошибка в определении времени.

Вы не учли вот эту проверку:
Код
    in    R5, ICR1H
    tst   R5
    brne  _do_not_correct_result

которая происходит перед "in AL, TIFR"
Цитата
2) Вполне возможно, что если прерывания TIM1_OVF и TIM1_CAPT возникли в течение указанного периода, то прерывание TIM1_OVF выполнится после TIM1_CAPT и ПОВТОРНО скорректирует результат в r3-r2 (не уверен на все 100, надо проверять).

Вот это помагает избежать данной проблеммы:
Код
    out   TIFR, AL

Цитата
3) Вход в прерывание TIM1_CAPT означает конец интервала измерения ...

или начало ....
Ну например если мы хотим измерять длительность единичного импульса на входе.
Цитата
Ну и последнее, в подобных случаях предпочитаю использовать конструкцию
Код
           subi   r2,-1      ;
           sbci   r3,-1      ;

Вместо эквивалентной
Код
           add    R2,сonst1  ;
           adc    R3,сonst0  ;

что очевидно лучше, поскольку освобождаются два регистра сonst0 и сonst1.

subi на регистрах R0-R15 ?! ню...ню...
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение Oct 9 2006, 20:15
Сообщение #52


Местный
***

Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986



Цитата
Ну и последнее, в подобных случаях предпочитаю использовать конструкцию
Код
           subi   r2,-1    ;
           sbci   r3,-1    ;


А не так, случайно:

Код
           subi   r16,low(-1)
           sbci   r17,high(-1)


Просто повезло, что в -1 младший и старший байты равны. но писать так не следует.

Сообщение отредактировал Леонид Иванович - Oct 9 2006, 20:16


--------------------
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 9 2006, 20:37
Сообщение #53


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Павезло так павезло smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 10 2006, 10:43
Сообщение #54


Ambidexter
*****

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



Цитата(GetSmart @ Oct 9 2006, 15:24) *
Цитата(=GM=)
Ничего не понял, поясните. Здесь никакой идеи, просто проверка содержимого r5:r4 на 0, только 0 может показать, что был перенос.
Я же написал, что там может быть и 10 и 100 и при этом быть перенос. Что Вы не поняли? Что в системе может быть больше чем эти два прерывания? Вы хоть поняли как предыдущая версия программы работала?


Как там (в r5-r4) может быть 10 или 100 и быть перенос? Его не может быть или я ничего не понимаю. Перенос может быть, если только в ICR1H-ICR1L (читай r5-r4) было 0хFFFF, а потом стало 0х0000. Никак не 10 или 100.

Ладно, отбросим предрассудки и недоразумения(:-), и начнем сначала.

1) Есть переменная в r7-r6-r5-r4, показывающая время. Содержимое регистров r5-r4 отражает содержимое аппаратных регистров захвата, по сути текущее время таймера1 на конец (или начало, не суть) измеряемого интервала. Каждые 65536 мкс содержимое таймера1 обнуляется и возникает перенос, который программно учитывается в регистрах r7-r6. Согласны?

2) Пойдем дальше. Как только возникает конец интервала, тут же происходит захват и мы имеем точное время записи, копируя содержимое ICR1L, ICR1H в r5-r4, и содержимое r3-r2 в r7-r6. Согласны?

3) Однако, если захват произойдет на 65536 микросекунде нашего таймера, возникнет перенос, который еще не учтен в r3-r2, и следовательно, в r7-r6. Как его учесть? Использовать ТЕКУЩИЙ аппаратный перенос от таймера1 НЕЛЬЗЯ, т.к. он никакого отношения к времени захвата не имеет. Согласны?

4) Наличие 0х0000 в r5-r4 означает, что в момент захвата произошло переполнение таймера1, и что перенос следует учесть в r7-r6. Согласны?

Ответьте по пунктам, если не трудно.

Цитата
Что в системе может быть больше чем эти два прерывания? Вы хоть поняли как предыдущая версия программы работала?

Я-то понял, а вот вы похоже нет, хотя вы один из авторов(:-). И при чем здесь количество прерываний?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 10 2006, 11:04
Сообщение #55


Ambidexter
*****

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



Цитата(Леонид Иванович @ Oct 9 2006, 19:15) *
А не так, случайно:
Код
           subi   r16,low(-1)
           sbci   r17,high(-1)

Просто повезло, что в -1 младший и старший байты равны, но писать так не следует.

Именно так и надо, так строже, и надёжнее - труднее ошибиться. Но прынцип тот же самый - вычитать минус 1, вместо того, чтобы прибавлять 1. Что очевидно лучше, чем регистровое вычитание, поскольку освобождаются два регистра сonst0 и сonst1.

Цитата(singlskv @ Oct 9 2006, 15:34) *
subi на регистрах R0-R15 ?! ню...ню...

Просто механически повторил ваш код, рука, так сказать, пронесла. А вы что, рады технической описке? Мелочь отметили, а главное пропустили, что не надо впустую инициализировать два регистра, да и сами регистры не нужны? Я вот на форуме стараюсь показать лучшее, что знаю сам, и поучиться лучшему у других.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 11:19
Сообщение #56


дятел
*****

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



Цитата(=GM= @ Oct 10 2006, 15:04) *
Что очевидно лучше, чем регистровое вычитание, поскольку освобождаются два регистра сonst0 и сonst1.
Цитата(singlskv @ Oct 9 2006, 15:34) *

subi на регистрах R0-R15 ?! ню...ню...

Просто механически повторил ваш код, рука, так сказать, пронесла. А вы что, рады технической описке? Мелочь отметили, а главное пропустили, что не надо впустую инициализировать два регистра, да и сами регистры не нужны? Я вот на форуме стараюсь показать лучшее, что знаю сам, и поучиться лучшему у других.

Если использовать subi, то мы занимаем под прерывание дефицитные R16-R32, а их всегда мало.
А вот R0-R15 как раз часто бывает в избытке, так что 2 лишних регистра const0 и const1
не очень жалко smile.gif
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 11:49
Сообщение #57


дятел
*****

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



Цитата(=GM= @ Oct 10 2006, 14:43) *
3) Однако, если захват произойдет на 65536 микросекунде нашего таймера, возникнет перенос, который еще не учтен в r3-r2, и следовательно, в r7-r6. Как его учесть? Использовать ТЕКУЩИЙ аппаратный перенос от таймера1 НЕЛЬЗЯ, т.к. он никакого отношения к времени захвата не имеет.

Код
                          <---- ICR1=FFFF  момент захвата
                          <---- TCNT1=FFFF
TIM1_CAPT:
                              <---- ICR1=FFFF начало обработки прерывания
                              <---- TCNT1=5
                              <---- TOV1=1
    in    _Sreg,SREG
    in    R4, ICR1L     <---- R4=FF
    in    R5, ICR1H     <---- R5=FF
    tst   R5                <---- R5==0 ???
    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
    reti
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 10 2006, 12:51
Сообщение #58


Ambidexter
*****

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



Чудак-человек, я согласен, что практически ваша программа будет работать, хотя логика запутанная(:-).

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

Пусть одновременно возникло два прерывания: захват и, другое, более приоритетное.
Пусть на момент захвата ICR1=00FF. Приоритетное прерывание начнет обрабатываться первым и пусть оно обрабатывается, скажем, 270 мкс. Поскольку таймер работает параллельно и независимо от приоритетного прерывания, возникнет OVF1=1.

Приоритетное прерывание закончило работу, начинает работать ваше прерывание по захвату.
Оно проверяет r5=0? Да. Проверяет далее OVF1=1? Да. И корректирует содержимое r3-r2 и, соответственно, r7-r6. А это неправильно. Как-то так.

И последний интересный вопрос, ответ на который я пока не знаю. Если прерывания TIM1_OVF и TIM1_CAPT возникли одновременно, и стало выполняться прерывание TIM1_CAPT, а прерывание TIM1_OVF дожидается своей очереди, вы уверены, что можно его снять, сбросив TOV1? В документации ничего не нашел по этому поводу.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 13:23
Сообщение #59


дятел
*****

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



Цитата(=GM= @ Oct 10 2006, 16:51) *
Пусть одновременно возникло два прерывания: захват и, другое, более приоритетное.
Пусть на момент захвата ICR1=00FF. Приоритетное прерывание начнет обрабатываться первым и пусть оно обрабатывается, скажем, 270 мкс. Поскольку таймер работает параллельно и независимо от приоритетного прерывания, возникнет OVF1=1.

Приоритетное прерывание закончило работу, начинает работать ваше прерывание по захвату.
Оно проверяет r5=0? Да. Проверяет далее OVF1=1? Да. И корректирует содержимое r3-r2 и, соответственно, r7-r6. А это неправильно. Как-то так.

ICR1=00FF
TCNT1=00FF
пусть прошло 270мкс =010E время обработки другого прерывания
ICR1=00FF
TCNT1=00FF+010E=020D
r5=0 ? Да.
OVF1=1 ? нет
итого: r3-r2 не корректируем
Цитата
И последний интересный вопрос, ответ на который я пока не знаю. Если прерывания TIM1_OVF и TIM1_CAPT возникли одновременно, и стало выполняться прерывание TIM1_CAPT, а прерывание TIM1_OVF дожидается своей очереди, вы уверены, что можно его снять, сбросив TOV1? В документации ничего не нашел по этому поводу.

фраза из даташита:

TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is
executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location.


На самом деле Вы привели просто неудачный пример.
Проблемма с длинным прерыванием действительно есть, и выглядит она вот так:

Int0: <---длинное прерывание >256 тактов
...............
TCNT1=0 <--- здесь переполнение TOV1=1
..............
ICR=0101h <--- здесь захват
.............
reti

CAPT: <--- сюда попадаем сразу после Int0
..............
in r4,ICR1L
in r5,ICR1H <--- r5=01 не корректируем, а зря smile.gif
<--- TOV1=1
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Oct 10 2006, 13:25
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(singlskv @ Oct 10 2006, 14:19) *
Цитата(=GM= @ Oct 10 2006, 15:04) *

Что очевидно лучше, чем регистровое вычитание, поскольку освобождаются два регистра сonst0 и сonst1.
Цитата(singlskv @ Oct 9 2006, 15:34) *

subi на регистрах R0-R15 ?! ню...ню...

Просто механически повторил ваш код, рука, так сказать, пронесла. А вы что, рады технической описке? Мелочь отметили, а главное пропустили, что не надо впустую инициализировать два регистра, да и сами регистры не нужны? Я вот на форуме стараюсь показать лучшее, что знаю сам, и поучиться лучшему у других.

Если использовать subi, то мы занимаем под прерывание дефицитные R16-R32, а их всегда мало.
А вот R0-R15 как раз часто бывает в избытке, так что 2 лишних регистра const0 и const1
не очень жалко smile.gif


Хотел бы отметить два факта. Во-первых просто поразительно насколько у людей разные интересы. smile.gif На мой взгляд совсем незначительная проблема вызвала серьёзный интерес и бурную деятельность. smile.gif

Во-вторых. Хотя я (как все) и применяю вычитание вместо сложения, тем не менее я делаю ещё так. Один из регистров в младшей области обзываю Vol0 и очищаю его. Ну и дальше работаю с ним. Это помогает в разных ситуациях. типа sts xxx,Vol0... inc/adc ... add Zl,wl/adc Zh,Vol0 ...
Где-то (по моему в PIC) подобное на уровне архитектуры применяется.
Go to the top of the page
 
+Quote Post
smk
сообщение Oct 10 2006, 14:09
Сообщение #61


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



По моему скромному мнению, мне очень понравилась идея, ссылка на которую дана в этой теме. Ну а по своему опыту скажу, что во время такого измерения следует допускать только те операции, которые собственно не счет микросекунд, что занимают не более частота кварца/1Мгц - 1 тактов. Отладку такой проги можно делать только в AVR Studio. Одним таймером считать другой.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 10 2006, 14:14
Сообщение #62


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Ой-Ой-Ой. smile.gif
Ладно, господа. Я вас примирю. Используем только const0, в которой храним -1. И уже sub/sbc с этой константой и младшими 16 регистрами. Итого теряется толька одын регистр.

=GM=
Читайте внимательно ПДФ-ы. Там всё есть. При "ручном" сбросе TOV1 прерывание по переполнению уже не обрабатывается.

Теперь про ICR1H/ICR1L объясняю в последний раз для особо трудных. В системе есть высокоприоритетное прерывание скажем длительностью 100 мкс. Вдруг оно возникает когда в TIMER=FFE0h. Соответственно оно закончится когда в таймере будет 0044h. Однако (случайно так) захват происходит когда в таймере 0020h. Что мы видим? Что Вы видете? ICR1H/ICR1L = 0020h. TOV1 = 1. Вас это удивляет? Как только высокоприоритетное прерывание заканчивается, то прерывание по переполнению не выполняется (!), а выполняется прерывание по захвату и обнаруживает то, что я уже написал. Вообще, я бы анализировал не совпадение с нулём регистра ICR1H, а только его старший бит. Таким образом максимально расширив диапазон допустимых высокоприоритетных прерываний.

Ещё вопросы?

ЗЫ. singlskv forever!


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 10 2006, 14:33
Сообщение #63


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Просто механически повторил ваш код, рука, так сказать, пронесла. А вы что, рады технической описке?

Таких описок у Вас тут уже немерено smile.gif
Не, мы не особо рады. Просто перед начинанием споров и критики вы должны были полностью разобраться в уже написанном коде и только когды вы полностью (!) поняли там каждую команду вы имеете право вносить свои предложения по упрощению. Если это послужит вам уроком, то мы думаю будем таки рады smile.gif

Цитата(=GM=)
Пусть одновременно возникло два прерывания: захват и, другое, более приоритетное.
Пусть на момент захвата ICR1=00FF. Приоритетное прерывание начнет обрабатываться первым и пусть оно обрабатывается, скажем, 270 мкс. Поскольку таймер работает параллельно и независимо от приоритетного прерывания, возникнет OVF1=1.

Это наверное тоже техническая описка? Только возникла она наверно ещё глубоко в мыслях. Мозг как бы обманул сам себя.

PS Без обид. Это я пока по-доброму критикую.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 10 2006, 14:36
Сообщение #64


Ambidexter
*****

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



Цитата(SasaVitebsk @ Oct 10 2006, 12:25) *
Хотел бы отметить два факта. Во-первых просто поразительно насколько у людей разные интересы. smile.gif На мой взгляд совсем незначительная проблема вызвала серьёзный интерес и бурную деятельность. smile.gif

Проблема не такая уж и незначительная. Постоянно натыкаюсь в сети на проекты частотомеров, цифровых шкал, где разработчики бездумно выставляют секундный интервал и подсчитывают количество приходящих импульсов, не пытаясь выжать максимальную точность. На 1 кГц они могут получить ТРИ значащих цифры!

Исходя из собственного опыта, скажу, что на 16-мегагерцовой атмеге можно измерить частоту до 3.2 МГц с точностью 0.2 Гц, т.е. с относительной погрешностью порядка 6Е-8. Причем на голой атмеге, не используя всяких прибамбасов в виде фпга и т.д. а если на входе поставить пять D-триггеров, то можно мерить 100 МГц с точностью 8 Гц. Получше, чем у некоторых промышленных частотомеров, как вам такая перспектива, э?

Цитата(SasaVitebsk @ Oct 10 2006, 12:25) *
Хотя я (как все) и применяю вычитание вместо сложения, тем не менее я делаю ещё так. Один из регистров в младшей области обзываю Vol0 и очищаю его. Ну и дальше работаю с ним. Это помогает в разных ситуациях. типа sts xxx,Vol0... inc/adc ... add Zl,wl/adc Zh,Vol0 ...

Я тоже так иногда делаю. Но чаще использую регистры временного хранения. Занес константу, сделал что-то и забыл.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 16:20
Сообщение #65


дятел
*****

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



Еще подправил код:
- заменил на одну константу ConstFF и sub/sbc
- за счет этого ввел новую константу _TOV1 которая является флагом TOV1 в TIFR
- что позволило избавиться от AL==R24 в прерывании TIM1_CAPT
- подправил код для длинных прерываний, сдвинул в "середину" ICR1H >=7F
Код
.def  ConstFF = R8
.def  _TOV1   = R9
.def  _Sreg   = R10
....
    clr   ConstFF
    dec   ConstFF
    ldi   R16, (1 << TOV1)
    mov   _TOV1, R16
....

; Input Capture:
TIM1_CAPT:
    in    _Sreg,SREG
    in    R4, ICR1L
    in    R5, ICR1H
    mov   R7, ConstFF
    lsr   R7
    cp    R5, R7
    brsh  _do_not_correct_result
    in    R6, TIFR
    and  R6, _TOV1
    breq  _do_not_correct_result
    out   TIFR, R6
    sub   R2, ConstFF
    sbc   R3, ConstFF
_do_not_correct_result:
    mov   R6, R2
    mov   R7, R3
    out   SREG,_Sreg
; <-- 32bit Result R7-R6-R5-R4 (MSB R7)
    reti
    
; Timer Overflow:
TIM1_OVF:
    in    _Sreg,SREG
    sub   R2, ConstFF
    sbc   R3, ConstFF
    out   SREG,_Sreg
    reti


Если кто найдет баги, телеграфируйте ... smile.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 10 2006, 17:15
Сообщение #66


Ambidexter
*****

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



Цитата(singlskv @ Oct 10 2006, 15:20) *
Еще подправил код:


Что-то мне разонравилось измерение по прерыванию. Наверное, надо делать без всяких прерываний, в фоне(:-).

Сообщение отредактировал =GM= - Oct 10 2006, 17:52


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 17:52
Сообщение #67


дятел
*****

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



Цитата(=GM= @ Oct 10 2006, 21:15) *
Мне кажется, зря вы здесь используете повторно r7, r6. Вдруг основная программа не успеет их обработать, а уже возникнет новое прерывание TIM1_CAPT. Понятно, что хочется съэкономить, но такая экономия может выйти боком(:-)

Нет, c R6,R7 там все в порядке.
вот этот код будет выполнен в конце прерывания TIM1_CAPT при любых условиях:
Код
    mov   R6,R2
    mov   R7,R3

так что здесь, ИМХО все ОК.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 18:06
Сообщение #68


дятел
*****

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



Цитата(=GM= @ Oct 10 2006, 21:15) *
Цитата(singlskv @ Oct 10 2006, 15:20) *

Еще подправил код:


Что-то мне разонравилось измерение по прерыванию. Наверное, надо делать без всяких прерываний, в фоне(:-).

Вам больше не нравятся прерывания ?
- Вы просто не умеете их правильно готовить (с) (не мой) smile.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 10 2006, 20:19
Сообщение #69


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(singlskv)
Код
    in    R5, ICR1H
    mov   R7, ConstFF
    lsr   R7
    cp    R5, R7
    brsh  _do_not_correct_result
Маленькое упрощение:
Код
    in    R5, ICR1H
    tst   R5
    brmi  _do_not_correct_result


Цитата(=GM=)
Как там (в r5-r4) может быть 10 или 100 и быть перенос? Его не может быть или я ничего не понимаю. Перенос может быть, если только в ICR1H-ICR1L (читай r5-r4) было 0хFFFF, а потом стало 0х0000. Никак не 10 или 100.
...........
Я-то понял, а вот вы похоже нет, хотя вы один из авторов(:-). И при чем здесь количество прерываний?
...........
Я вот на форуме стараюсь показать лучшее, что знаю сам, и поучиться лучшему у других.

Вы уже наконец поняли о чём я говорил? Если да, то ничего не хотите добавить к этому?

Цитата(=GM=)
Что-то мне разонравилось измерение по прерыванию. Наверное, надо делать без всяких прерываний, в фоне(:-).

smile.gif
Особенно если учесть, что раньше был другой текст smile.gif smile.gif

Сообщение отредактировал GetSmart - Oct 10 2006, 20:41


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 10 2006, 20:58
Сообщение #70


дятел
*****

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



[quote name='GetSmart' date='Oct 11 2006, 00:19' post='163416']
[quote=singlskv]
Код
    in    R5, ICR1H
    mov   R7, ConstFF
    lsr   R7
    cp    R5, R7
    brsh  _do_not_correct_result
[/quote]Маленькое упрощение:
Код
    in    R5, ICR1H
    tst   R5
    brmi  _do_not_correct_result

Ой... , Вы правы (вот и я научился чему то новому в этом топике smile.gif )
Уже не помню почему, но у меня стойко закрепилось в мозгу, что после
tst Rxx нужно использовать breq/brne, jz/jnz, и т.д.
Спасибо... smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 10 2006, 22:32
Сообщение #71


кекс
******

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



Цитата(SasaVitebsk @ Oct 10 2006, 16:25) *
Хотел бы отметить два факта. Во-первых просто поразительно насколько у людей разные интересы. smile.gif На мой взгляд совсем незначительная проблема вызвала серьёзный интерес и бурную деятельность. smile.gif

Дык задача многосторонняя, от того и интерес. ;>
В системе с одноуровневым КП и таймером с "окном" ~1-10% от интервала измерений, обслуживать несколько прерываний и при этом не терять точность. Нельзя сказать, что это тривиальная задача для AVR.

Ну и плюс простота кода - не нужно долго вникать. smile.gif


=GM=- это конечно здорово, что вы попытались упростить код, правильно мыслите, однако прислушайтесь к совету GetSmart - перед всякой критикой нужно полностью разобраться в том, что уже есть, иначе критика вызывает улыбку.


GetSmart
Я таки все так же против увеличения латентности других прерываний и использования проверки последнего бита. 256 тактов "запаса" еще как-то понятно, а вот на что может понадобиться больше - уже нет. Тем паче "флагманские" прерывания (которые могут потребовать относительно длительной обработки) обладают более низким приоритетом чем T1_CAPT.
Половина таймера это на самом деле очень много. И если в системе есть обработчики такой длительности ~32k тактов, то это значит, что мы можем ошибиться уже в обратную сторону - "через круг таймера".
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 10 2006, 23:11
Сообщение #72


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



defunct
Скучали тут без Вас smile.gif

А почему все думают, что у АВР одноуровневой КП? Может уже я чего-то не знаю?

Цитата(defunct)
Я таки все так же против увеличения латентности других прерываний и использования проверки последнего бита.
Так... Вы - против, я - за. Что будем с этим делать?
Ограничение только в том, что любое допустимое в системе прерывание обязано занимать время меньшее, чем минимум времени между двумя исследуемыми импульсами. А уж сколько оно будет на практике, 100 мкс или 30 мс - это должен учитывать разработчик конкретного устройства. Эта программа даёт ему такую возможность вплоть до 32 мс.

Поясните, плиз, как можно ошибиться уже в обратную сторону?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 10 2006, 23:14
Сообщение #73


кекс
******

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



Цитата(GetSmart @ Oct 11 2006, 02:01) *
А почему все думают, что у АВР одноуровневой КП? Может уже я чего-то не знаю?

А почему "думают"? ;>
Об этом в ДШ сказано.

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts
are disabled. The user software can write logic one to the I-bit to enable nested interrupts.
All enabled interrupts can then interrupt the current interrupt routine. The I-bit is
automatically set when a Return from Interrupt instruction – RETI – is executed.
....
When the AVR exits from an interrupt, it will always return to the main program and execute
one more instruction before any pending interrupt is served.


Если к примеру сравнить с C51, то в нем предусмотрено два уровня, L0, L1.
Когда выполняется обработчик L0, то другие прерывания с приоритетом L0 не могут быть вызваны, зато прерывание с приоритетом L1 - может. В AVR такого нет по определению, а установка флага I внутри обработчика прерывания, можно назвать не иначе как "глюкодром" smile.gif , ведущий к deadlock основной программы.

Цитата
Так... Вы - против, я - за. Что будем с этим делать?

Ничего smile.gif оставим как есть - 2 варианта.
Не бывает единственно верных решений.

Цитата
Поясните, плиз, как можно ошибиться уже в обратную сторону?

по тактам начиная с такта i:

i - переход на длительный обработчик (пусть будет Uart0) TCNT1 = 0x7FFE
i + 0x1 - срабатывание захвата TIF1 = 1, ICR = 0x7FFF, TOV1 = 0.
i + 0x7FF8 - Uart0 обработка завершена выполнение RETI (4 такта), TCNT1 = FFF6, TOV1 = 0
i + 0x7FFC - возврат в основную, выполнение хотя бы одной команды, TCNT1 = 0xFFFA
i + 0x7FFD - начало входа в обработчик (не менее 4х тактов) T1_ICAP, TCNT1 = 0xFFFB, TOV1 = 0
i + 0x8001 - первая команда обработчика T1_ICAP, TCNT1 = 0xFFFF, TOV1 = 0
i + 0x8002 - вторая команда обработчика T1_ICAP, TOV1 = 1 <------ !
ну и коррекция рез-тата +0x10000, т.к. попадаем под условие коррекции (ICR < 32k, TOV=1).

Эта одна из возможных иллюстраций. На самом деле все ухудшается еще и наличием более высокоприоритетных чем T1_ICAP прерываний от T2 и INTx и т.п.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 10 2006, 23:34
Сообщение #74


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата
как "глюкодром" smile.gif
Класс!
Не, ну не надо так уж клеймить АВР. Минус только в отсутствии аппаратного запоминания текущего приоритета и запрета низкоприоритетных прерываний и текущего. При большом желании можно легко (!) сделать двухуровневой КП (трёх) если вручную запрещать текущее прерывание, а потом устанавливать флаг I. Плохо только что стека маловато.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 10 2006, 23:57
Сообщение #75


кекс
******

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



Цитата(GetSmart @ Oct 11 2006, 02:34) *
Не, ну не надо так уж клеймить АВР.

Не "клеймлю" я его ;>
AVR - отличный процессор. Просто я не сторонник изощренных путей написания программ.
На мой взгляд, надо подстраиваться под железо и писать соответствующие обработчики прерываний. Для AVR они должны быть короткими, т.к. нет многоуровневого КП.

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

Цитата
Минус только в отсутствии аппаратного запоминания текущего приоритета и запрета низкоприоритетных прерываний и текущего.

Это не минус, это фича wink.gif
Для многих задач это плюс т.к. одноуровневый КП избавляет программиста от некоторых проблем синхронизации.

Цитата
При большом желании можно легко (!) сделать двухуровневой КП (трёх) если вручную запрещать текущее прерывание, а потом устанавливать флаг I. Плохо только что стека маловато.

Можно, но не нужно. Проще просто подобрать другой камень когда это действительно надо.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 11 2006, 02:49
Сообщение #76


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(defunct)
i - переход на длительный обработчик (пусть будет Uart0) TCNT1 = 0x7FFE
i + 0x1 - срабатывание захвата TIF1 = 1, ICR = 0x7FFF, TOV1 = 0.
i + 0x7FF8 - Uart0 обработка завершена выполнение RETI (4 такта), TCNT1 = FFF6, TOV1 = 0
i + 0x7FFC - возврат в основную, выполнение хотя бы одной команды, TCNT1 = 0xFFFA
i + 0x7FFD - начало входа в обработчик (11 тактов) T1_ICAP, TCNT1 = 0xFFFB, TOV1 = 0
i + 0x8008 - первая команда обработчика T1_ICAP, TOV1 = 1 <------ !
ну и коррекция рез-тата +0x10000, т.к. попадаем под условие коррекции (ICR < 32k, TOV=1).
Ну зачем же такой "экстремальный" пример приводить? Который, кстати, алгоритм-то не дискредитирует smile.gif Я же не обещал ровно до 32К тактов дополнительного прерывания. Ваш пример всего-лишь указывает, что максимальное время прерывания = 32К-хх тактов. Скажем 31К или 32000 такта 100% хватит для работоспособности проги. А в Вашей версии будет то же самое = 256-хх тактов.
Вобщем недостатка как такового в моей версии и нету. Блин sad.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 11 2006, 10:54
Сообщение #77


Ambidexter
*****

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



Цитата(singlskv @ Oct 10 2006, 17:06) *
Цитата(=GM= @ Oct 10 2006, 21:15) *

Цитата(singlskv @ Oct 10 2006, 15:20) *

Еще подправил код:

Что-то мне разонравилось измерение по прерыванию. Наверное, надо делать без всяких прерываний, в фоне(:-).

Вам больше не нравятся прерывания ?
- Вы просто не умеете их правильно готовить (с) (не мой) smile.gif

А что там уметь? Прерывание, оно и в Африке-прерывание(:-).
По делу. Выразился не так, как хотел. Мне не нравится длинное прерывание, которое вдруг стало накладываться на наши два. Откуда бы ему взяться в задаче по измерению временного интервала? Поэтому предлагаю сделать откат назад и исключить третье прерывание.

Теперь поясню, почему пропал мой предыдущий текст, а то народ уже и этим тычет(:-). Вчера к концу рабочего дня набрал почти ведро маслят, представьте, в октябре! Ну я разволновался, как же дилишез(:-), вследствие такого события случайно удалил почти весь текст. А хотел ведь просто добавить то, что вы увидели.

Вот еще один вопросик, требующий внимания. Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь?

И моим оппонентам на будущее. Я говорю то, что говорю, не надо искать второго смысла, ОК? И замечайте смайлики иногда.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 11 2006, 11:10
Сообщение #78


Ambidexter
*****

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



Цитата(singlskv @ Oct 10 2006, 16:52) *
Цитата(=GM= @ Oct 10 2006, 21:15) *

Мне кажется, зря вы здесь используете повторно r7, r6. Вдруг основная программа не успеет их обработать, а уже возникнет новое прерывание TIM1_CAPT. Понятно, что хочется съэкономить, но такая экономия может выйти боком(:-)

Нет, c R6,R7 там все в порядке.
вот этот код будет выполнен в конце прерывания TIM1_CAPT при любых условиях:
Код
    mov   R6,R2
    mov   R7,R3

так что здесь, ИМХО все ОК.

Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 11 2006, 16:06
Сообщение #79


дятел
*****

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



Цитата(=GM= @ Oct 11 2006, 15:10) *
Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата.

А как Вы в основной программе планируете узнавать что произошел второй захват ? smile.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 11 2006, 16:25
Сообщение #80


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь?
Ну дык у АВР есть возможность вызывать прерывание по любому изменению состояния входа. Надо только при запуске правильно инициализироваться (учесть текущее состояние), а дальше - понеслась.

Ведро маслят... Это многое объясняет... Как-нить при случае тоже ляпну такое smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
AVR
сообщение Oct 11 2006, 17:25
Сообщение #81


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

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



Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... biggrin.gif


--------------------
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 11 2006, 17:30
Сообщение #82


дятел
*****

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



Цитата(AVR @ Oct 11 2006, 21:25) *
Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... biggrin.gif

ну точно OFF - в топку smile.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 11 2006, 17:43
Сообщение #83


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(AVR @ Oct 11 2006, 23:25) *
Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... biggrin.gif


___________
Please, don't kill me smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
CD_Eater
сообщение Oct 11 2006, 17:59
Сообщение #84


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

Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595



Цитата(defunct @ Oct 11 2006, 03:57) *
Цитата

Минус только в отсутствии аппаратного запоминания текущего приоритета и запрета низкоприоритетных прерываний и текущего.
Это не минус, это фича wink.gif
Для многих задач это плюс т.к. одноуровневый КП избавляет программиста от некоторых проблем синхронизации.
Конечно, гарантия непрерываемости текущего обработчика прерываний даёт возможность, например, использовать некоторые регистры или ячейки памяти в качестве общих временных для всех обработчиков прерываний без сохранения их предыдущего состояния, а также ограничивает размер стека - это удобно. С другой стороны, на ранних AVR-ках с аппаратным стеком (на 3 вложенных вызова подпрограмм и прерываний) иначе и быть не могло. А далее памяти прибавили, но основу ядра менять не стали...

Цитата
Цитата
При большом желании можно легко (!) сделать двухуровневой КП (трёх) если вручную запрещать текущее прерывание, а потом устанавливать флаг I. Плохо только что стека маловато.

Можно, но не нужно. Проще просто подобрать другой камень когда это действительно надо.
Зачем выбирать другой камень, если вопрос лишь в доработке софта ?
Менять камень нужно лишь в случае, если он не удовлетворяет требованиям к железу.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 11 2006, 20:51
Сообщение #85


дятел
*****

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



Цитата(defunct @ Oct 11 2006, 03:14) *
Цитата(GetSmart @ Oct 11 2006, 03:11) *

Так... Вы - против, я - за. Что будем с этим делать?

Ничего smile.gif оставим как есть - 2 варианта.
Не бывает единственно верных решений.

Осмелюсь предложить следующее решение:
Код
.def  ConstFF = R8
.def  _TOV1   = R9
.def  _Sreg   = R10
....
    clr   ConstFF
    dec   ConstFF
    ldi   R16, (1 << TOV1)
    mov   _TOV1, R16
....

; Input Capture:
TIM1_CAPT:
    in    _Sreg,SREG
    in    R4, ICR1L
    in    R5, ICR1H
    cp    R5, _TOV1
    brsh  _do_not_correct_result
    in    R6, TIFR
    and   R6, _TOV1
    breq  _do_not_correct_result
    out   TIFR, R6
    sub   R2, ConstFF
    sbc   R3, ConstFF
_do_not_correct_result:
    mov   R6, R2
    mov   R7, R3
    out   SREG,_Sreg
; <-- 32bit Result R7-R6-R5-R4 (MSB R7)
    reti

Здесь уже кому как повезет, куда _TOV1 попадет в TIFR, такой и будет запас
для длинных прерываний.
Да и код, ИМХО становится намного понятнее biggrin.gif

А если серьезно, то запас для других прерываний нужно оставлять в зависимости
от конкретной задачи.
Например, вместо TIM1_OVF мы можем использовать TIM1_CAPTA со значением
OCR1A<32K и тогда запас должен быть другим, тогда будет рулить такой код:
Код
    in    R4, ICR1L
    in    R5, ICR1H
    in    R7, OCR1AH
    lsr   R7
    cp    R5, R7
    brsh  _do_not_correct_result

Ну конечно на определенном диапазоне значений OCR1A
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 12 2006, 09:31
Сообщение #86


Ambidexter
*****

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



Цитата(singlskv @ Oct 11 2006, 15:06) *
Цитата(=GM= @ Oct 11 2006, 15:10) *

Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата.

А как Вы в основной программе планируете узнавать что произошел второй захват ? smile.gif

А вы у GetSmart спросите, он всё знает(:-). Спокойно, GetSmart, шютю я(:-)

Чуть посерьёзнее. Я вам про экономию регистров в прерывании говорю, "которых всегда не хватает", а вы плавно меняете тему. Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l? Никакой разницы нет. Почти. Зато экономится два регистра!

Ну а по делу, думаю есть несколько подходов.

1) Есть две переменные, скажем, oldTime и newTime (ваши r7-r6-r5-r4). Прерывание захвата должно переписывать содержимое newTime в oldTime, и только затем обновлять newTime. Основная программа в любое удобное для себя время(:-) определяет длительность интервала, просто вычитая содержимое oldTime из newTime.

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

Цитата(GetSmart @ Oct 11 2006, 15:25) *
Цитата(=GM=)
Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь?
Ну дык у АВР есть возможность вызывать прерывание по любому изменению состояния входа. Надо только при запуске правильно инициализироваться (учесть текущее состояние), а дальше - понеслась.

Неправильно. В том то и дело, что не один раз при запуске программы надо инициализироваться, а каждый раз при входе в захват(:-(. Потому что на четных захватах вы ловите переход 0-1 (начало импульса), а на нечетных захватах вы ловите 1-0 (конец импульса). Я и спрашивал, перенастраивать ICES1 каждый раз или есть другой способ, попроще?

Цитата(GetSmart @ Oct 11 2006, 15:25) *
Ведро маслят... Это многое объясняет... Как-нить при случае тоже ляпну такое smile.gif

GetSmart, хорош бурчать, это у вас так что проявляется(:-)? Не злитесь, ляпните что-нибудь или тяпните, разрядка придёт, поверьте(:-). Добавлю специально для вас. Напротив моих окон стоит бангало, под ним живет более 20 диких кроликов, смешные такие...А недавно видел как ворона ссорилась с белкой, наскакивали друг на друга, прям как вы на меня(:-).

GetSmart, жена маслята уже посолила, вот. Белые тут тоже водятся, но ехать далеко, в Нью Форист, неохота...


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 12 2006, 10:18
Сообщение #87


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
GetSmart, хорош бурчать, это у вас так что проявляется(:-)?
Это веселуха. Заметьте, над другими тоже. А вообще, люблю "поржать" над чужими глупостями. Это после длииинного отпуска у меня такой бзик. Должен пройти.
Цитата
Я и спрашивал, перенастраивать ICES1 каждый раз или есть другой способ, попроще?
Нету.
Цитата
А вы у GetSmart спросите, он всё знает(:-)
Нее, я мало знаю. На всём форуме я очень мало где появляюсь. То есть знаю совсем немного тем, но обычно очень глубоко.

Больше всего меня прикололо это: когда вам показали как безболезненно доработать прогу возможностью обработки дополнительных прерываний вы выдали фразу, что вам прерывания не нравятся и надо делать вообще без них. Надо было видеть моё лицо smile.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 15 2006, 02:25
Сообщение #88


кекс
******

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



Цитата(=GM= @ Oct 12 2006, 12:31) *
А недавно видел как ворона ссорилась с белкой, наскакивали друг на друга, прям как вы на меня(:-).

Дык, эта, если смотреть со стороны, здесь все замечания вам по делу были сказаны, а вы все в шутку да в обидку воспринимаете..
Что ни пост - то перл:

особливо это:
Цитата
Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l?

Ну уж никак не в аппаратно зависимых регистрах, которые нам абсолютно неподконтрольны.
Вы что, правда не понимаете, что можно не успеть вычитать icr1h-icr1l до того как случится следующий захват? либо например наткнуться на ситуацию когда в момент вычитки L, произойдет следующий захват.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 16 2006, 13:06
Сообщение #89


Ambidexter
*****

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



Цитата(defunct @ Oct 15 2006, 01:25) *
Что ни пост - то перл: особливо это:
Цитата
Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l?

Ну уж никак не в аппаратно зависимых регистрах, которые нам абсолютно неподконтрольны.
Вы что, правда не понимаете, что можно не успеть вычитать icr1h-icr1l до того как случится следующий захват? либо например наткнуться на ситуацию когда в момент вычитки L, произойдет следующий захват.

Я и не такие перлы могу выдавать(:-). Но вообще-то, в нашем случае никакой разницы на самом деле нет, посудите сами, как только произошел захват, возникло прерывание, в котором регистры icr1h-icr1l читаются и переписываются в r5-r4, т.е. и icr1h-icr1l, и r5-r4 изменяются практически одновременно (макс разница 32 мс, если есть длинное прерывание). Естественно предполагается, что вы должны успеть обработать r7-r6-r5-r4 до следующего захвата, который может случиться через секунду (по условию задачи). Ну и спрашивается, зачем тратить два регистра МК, если можно с таким же успехом хранить данные в регистрах захвата?

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

Вы-то сами понимаете, что при наличии длинного прерывания наступит крах вашей системы прерываний, если, скажем, возникнет два прерывания захвата в течение 65 мс?

По существу, во время дискуссии выплеснули ребеночка, стали решать задачу измерения интервала при наличии длинного прерывания и меры по его устранению, хотя автор просил совета по измерению длительности секундных импульсов, а не периода, следовательно, по моему мнению, время между импульсами может быть любым, пусть, скажем, будет допустимый минимум 50 мкс между спадом одного импульса и фронтом другого, ну и где будут длинные прерывания? Или другими словами, минимальное время между двумя захватами должно составлять 50 мкс, что означает отказ от других прерываний, будь они длинные или короткие...

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

Что ещё? На справедливую критику не обижаюсь, с несправедливой борюсь по мере сил(:-), и посмеяться и пошутить люблю, но по-доброму.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 18 2006, 11:44
Сообщение #90


кекс
******

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



Цитата(=GM= @ Oct 16 2006, 16:06) *
Я и не такие перлы могу выдавать(:-). Но вообще-то, в нашем случае никакой разницы на самом деле нет, посудите сами, как только произошел захват, возникло прерывание, в котором регистры icr1h-icr1l читаются и переписываются в r5-r4, т.е. и icr1h-icr1l, и r5-r4 изменяются практически одновременно (макс разница 32 мс, если есть длинное прерывание). Естественно предполагается, что вы должны успеть обработать r7-r6-r5-r4 до следующего захвата, который может случиться через секунду (по условию задачи). Ну и спрашивается, зачем тратить два регистра МК, если можно с таким же успехом хранить данные в регистрах захвата?

Если же вы не успели, то произойдет новый захват, r5-r4 тоже испортятся, так что тут ничто не поможет, какая разница, что испорчено?

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

Если же рез-тат будет храниться в r7-r6-r5-r4, то мы можем запретить флаг I при обращении к этой 32х битной переменной, и тем самым обезопасить себя от последствий описанного случая.

Учить матчасть smile.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 18 2006, 14:14
Сообщение #91


Ambidexter
*****

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



Цитата(defunct @ Oct 18 2006, 10:44) *
Затем, что прерывание может произойти именно в момент вычитки значения, и мы можем прочитать недостоверные данные.

Если же рез-тат будет храниться в r7-r6-r5-r4, то мы можем запретить флаг I при обращении к этой 32х битной переменной, и тем самым обезопасить себя от последствий описанного случая.

Here we go! Я ж вам сконструировал реальный пример. Ну запретили вы все прерывания, потом пришло два захвата до начала вашей обработки с интервалом в 50 мкс, и где будут данные от первого захвата, скажите? Правильно, в глубокой попе, а не в r7-r6-r5-r4.

Как-то вы несистемно подходите к задаче измерения интервалов. Ну написали вы программку чтения данных из регистров icr1, дальше-то что делать? Ждать когда завершится длинное прерывание и фоновая программа наконец запретит прерывания, соизволит переписать r7-r6-r5-r4 в память и разрешит прерывания заново? Данах такую программу измерения! Пока ваша программа будет жевать сопли, там уж десять раз новый захват может возникнуть!

На мой взгляд, чтобы программа обработки захвата была максимально быстрой, она должна записывать время захвата в буфер именно в программе обработки. Если вы согласны с этим, то какая разница откуда писать в буфер? Из r7-r6-r5-r4, или из r7-r6-icr1h-icr1l, или из r3-r2-icr1h-icr1l? Да без разницы! Но лучше из r3-r2-icr1h-icr1l (с возможной коррекцией), т.к. экономятся регистры и быстрее работает. Ну и никаких других прерываний, измерение интервалов само по себе ответственное дело(:-).

Цитата(defunct @ Oct 18 2006, 10:44) *
Учить матчасть smile.gif

Согласен, учить не вредно (хотя конкретно здесь сказано вами не к месту). Но вот посмотрел еще раз на 128-ю атмегу и нашел способ измерения интервалов с точностью 0.5 мкс (полмикросекунды!) Точность удвоена, ура три раза!

Кстати, почему никто не отвечает на вопрос что требуется измерение длины импульса (фронт и спад), а не периода (два фронта или два спада)? Все согласны что ли?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 18 2006, 14:43
Сообщение #92


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Как-то вы несистемно подходите к задаче измерения интервалов.
А вы типа полный системщик. Тут вам предложили просто наброски проги с самыми сложными местами. Базару нет - её можно улучшить под конкретную задачу. Похоже только вам здесь хочется её воплотить в железе. Делайте. Напишите и выложите тут свою прогу, а мы её дружно покритикуем. Даже поможем улучшить. А то ведь вы порой бревна в глазу не замечаете. Так что будет интересно и нам и вам. А может даже весело.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 18 2006, 16:04
Сообщение #93


кекс
******

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



Цитата(=GM= @ Oct 18 2006, 17:14) *
хотя конкретно здесь сказано вами не к месту

Вам виднее.


Цитата
Кстати, почему никто не отвечает на вопрос что требуется измерение длины импульса (фронт и спад), а не периода (два фронта или два спада)? Все согласны что ли?

Потому что это уже косметика.

Цитата
Если вы согласны с этим, то какая разница откуда писать в буфер? Из r7-r6-r5-r4, или из r7-r6-icr1h-icr1l, или из r3-r2-icr1h-icr1l?

Разница огромная.
Я предпочту запретить прерывания и прочитать достоверное значение из защищенного от изменений буфера. После чего, разрешив прерывания, будет выполнено обновление переменной и т.д. Этим я обезопашу себя и вас от дурацких вопросов в будущем - "окуда появилось это значение". Вы же со своей реализацией и вычиткой icr от таких вопросов ничем не застрахованы, если Вам с вашим системным подходом до сих пор не ясна проблема, то я попробую озвучить ее прямым текстом:
- пол переменной у вас может быть прочитано из одного семпла, а вторая половина - из второго.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 18 2006, 17:17
Сообщение #94


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



defunct
Любопытная вещь. Это я где-то уже видел и проверил для АВРов. Там есть временный регистер для защёлкивания старших 8 бит при чтении младших. То бишь читая младший, а затем старший регистр гарантированно прочитается цельное значение.

=GM=
Читать ICR1L и ICR1H по-любому придётся вначале в регистры. Там же проверка стоит старшего байта. Ну а потом прямо в прерывании можно вычитать все 4 байта из предыдущих 4 байт и сувать куда-нибудь. Например в кольцевой буфер в ОЗУ. R6 и R7 можно будет не использовать. Но вообще, особой выгоды в экономии и нет. Лишь бы правильно работала. Апосля можно переключать полярность защёлкивания и желлательно сразу проверить полярность на входе.

Сообщение отредактировал GetSmart - Oct 18 2006, 17:40


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 18 2006, 20:07
Сообщение #95


дятел
*****

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



Цитата(=GM= @ Oct 18 2006, 18:14) *
Но вот посмотрел еще раз на 128-ю атмегу и нашел способ измерения интервалов с точностью 0.5 мкс (полмикросекунды!) Точность удвоена, ура три раза!

Ну давайте сразу же определимся, в конечном итоге мы измеряли не мкс а такты проца.

То есть Вы утверждаете, что Вы можете измерить временной интервал, с точностью 0,5 такта
процессора, который измеряет этот временной интервал ?

Ну поделитесь кодом, что ли. a14.gif

Если это know-how, и Вы собираетесь на этом заработать, то тогда
скажите как будет выглядеть возвращаемое значение вашего измерения
например для промежутков 50тактов 50,5тактов 51тактов и т.д.....
Мы, как Ваши потенциальные клиенты должны (перед покупкой Вашего алгоритма)
знать какие выходные данные мы получим.
С нетерпением жду Ваших ответов smile.gif

P.S. Нельзя ли модернизировать Ваш алгоритм для получения 1/16 такта процессора,
очень надо...
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 19 2006, 14:55
Сообщение #96


Ambidexter
*****

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



Цитата(GetSmart @ Oct 18 2006, 13:43) *
Цитата(=GM=)
Как-то вы несистемно подходите к задаче измерения интервалов.
А вы типа полный системщик. Тут вам предложили просто наброски проги с самыми сложными местами. Базару нет - её можно улучшить под конкретную задачу.

Нет конечно, но хотелось бы(:-). Похоже вам слово системщик, как быку красная тряпка(:-), не обижайтесь. Несистемный подход означает решение частной мелкой задачи, вместо того чтобы дать решение общей, пусть и крупными мазками. Вашу позицию понял, но не проникся(:-).
Цитата(GetSmart @ Oct 18 2006, 13:43) *
Похоже только вам здесь хочется её воплотить в железе. Делайте. Напишите и выложите тут свою прогу, а мы её дружно покритикуем. Даже поможем улучшить. А то ведь вы порой бревна в глазу не замечаете. Так что будет интересно и нам и вам. А может даже весело.

Да не хочется мне ее воплощать. Меня интересуют потенциальные возможности аврок. Единственное рациональное зерно, до которого я допер в результате долгой дискуссии - это возможность измерения времени импульса с точностью ПОЛТАКТА процессора, в нашем случае - 0.5 мкс.
Ну а чтобы было веселее, вот моя прога. Критикуйте на здоровье. Улучшайте. Сразу скажу, прога сырая, я ее не проверял, есть два сомнительных места, надеюсь, с помощью коллективного разума разрешим их.
Код
; В регистрах r23-r22-r21-r20 размещается время спада импульса
; В регистрах r19-r18-r17-r16 размещается время фронта импульса
; Регистровая пара X – два старших байта текущего времени
; Регистровая пара Y – текущий указатель в buffer (0х0100-0х01FF)
; Регистровая пара Z – переключатель фрагментов программы захвата

           .dseg                 ;01
buffer:    .org   0x0100         ;02
           .cseg                 ;03
           .org   0x0016         ;04 обработчик захвата1
tim1capt:  ijmp                  ;05 переключатель
           .org   0x001С         ;06 обработчик переполнения1
tim1ovf:   rjmp   overflow1      ;07

;<< фрагмент программы инициализации >>
;. . . . . . . .
           ldi    zl,low(rising) ;10
           ldi    zh,high(rising);11
           ldi    r16,0x00       ;12 захват по спаду
           mov    r15,r16        ;13
           ldi    r16,0x20       ;14 сброс ICF1
           mov    r14,r16        ;15
           ldi    r16,0x40       ;16 захват по фронту
           mov    r13,r16        ;17
;. . . . . . . .
;<< конец фрагмента программы инициализации >>
;
           .org   0x0100         ;22
rising:    in     r16,ICR1L      ;24 обработка фронта
           in     r17,ICR1H      ;24
           out    tccr1b,r15     ;25
           out    tifr,r14       ;26
           movw   r18,r26        ;27 r19-r18-r17-r16
           in     r10,SREG       ;28
           cpi    r17,0x00       ;29
           brne   ris1           ;30
           in     r24,tifr       ;31
           sbrs   r24,tov1       ;32
           rjmp   ris1           ;33
           subi   r16,low(-1)    ;34
           sbci   r17,high(-1)   ;35
ris1:      ldi    zl,low(falling);36
           out    SREG,r10       ;37
           sei                   ;38
           ret                   ;39
;
falling:   in     r16,ICR1L      ;50 обработка спада
           in     r17,ICR1H      ;51
           out    tccr1b,r15     ;52
           out    tifr,r14       ;53
           movw   r22,r26        ;54
           in     r10,SREG       ;55
           cpi    r17,0x00       ;56
           brne   fal1           ;57
           in     r24,tifr       ;58
           sbrs   r24,tov1       ;59
           rjmp   fal1           ;60
           subi   r21,low(-1)    ;61
           sbci   r22,high(-1)   ;62
fal1:      sub    r20,r16        ;63
           sbc    r21,r17        ;64
           sbc    r22,r18        ;65
           sbc    r23,r19        ;66
           st     y+,r20         ;67
           st     y+,r21         ;68
           st     y+,r22         ;69
           st     y+,r23         ;70
           ldi    yh,high(buffer);71
           ldi    zl,low(rising) ;72
           out    SREG,r10       ;73
           sei                   ;74
           ret                   ;75
;
; обработчик переполнения таймера1
overflow1: in     r10,SREG       ;90
           adiw   r26,1          ;91
           out    SREG,r10       ;92
           reti                  ;93


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 19 2006, 15:21
Сообщение #97


Ambidexter
*****

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



Цитата(singlskv @ Oct 18 2006, 19:07) *
Цитата(=GM= @ Oct 18 2006, 18:14) *

Но вот посмотрел еще раз на 128-ю атмегу и нашел способ измерения интервалов с точностью 0.5 мкс (полмикросекунды!) Точность удвоена, ура три раза!

Ну давайте сразу же определимся, в конечном итоге мы измеряли не мкс а такты проца.
То есть Вы утверждаете, что Вы можете измерить временной интервал, с точностью 0,5 такта
процессора, который измеряет этот временной интервал ?

Да, утверждаю. Для нашего случая тактовая частота равна 1 МГц, так что точность будет 0.5 мкс. А в общем случае, полтакта процессора.

Цитата(singlskv @ Oct 18 2006, 19:07) *
Ну поделитесь кодом, что ли. a14.gif
Если это know-how, и Вы собираетесь на этом заработать, то тогда
скажите как будет выглядеть возвращаемое значение вашего измерения
например для промежутков 50тактов 50,5тактов 51тактов и т.д.....
Мы, как Ваши потенциальные клиенты должны (перед покупкой Вашего алгоритма)
знать какие выходные данные мы получим.
С нетерпением жду Ваших ответов smile.gif
P.S. Нельзя ли модернизировать Ваш алгоритм для получения 1/16 такта процессора,
очень надо...

Кодом поделиться не могу, его просто нет. Есть плодотворная идея как это реализовать на голой атмеге128, и программа, кажется, будет несложной. Зарабатывать на этом я не собираюсь, хотя шут ее знает, может надо(:-)?
Возвращаемое значение будет точно также размещено в 4-х байтах, но одна единица будет соответствовать не длительности 1-го такта, а его половине, т.е. 100, 101, 102, 103 [тактов/2] вместо 50, 50.5, 51 [тактов].
По поводу модернизации. Можно и для 1/16 сделать, только с дополнительными прибамбасами(:-(. Вы лучше скажите, что вы хотите сделать, тогда можно поконкретнее ответить.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение Oct 19 2006, 17:20
Сообщение #98


дятел
*****

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



Цитата(=GM= @ Oct 19 2006, 18:55) *
Код
........................
........................

Не понял чем Ваш код принципиально отличается от того что мы здесь обсуждали.
Косметика ?
Только Вы умудрились сожрать под прерывания все старшие регистры
кроме R25, да еще и 4 младших.
Интересно, в основной программе Вы планируете для работы с константами
использовать только R25 ? А регистрами X,Y,Z вообще не пользоваться ?

Цитата(=GM= @ Oct 19 2006, 19:21) *
Цитата(singlskv @ Oct 18 2006, 19:07) *

Цитата(=GM= @ Oct 18 2006, 18:14) *

Но вот посмотрел еще раз на 128-ю атмегу и нашел способ измерения интервалов с точностью 0.5 мкс (полмикросекунды!) Точность удвоена, ура три раза!

Ну давайте сразу же определимся, в конечном итоге мы измеряли не мкс а такты проца.
То есть Вы утверждаете, что Вы можете измерить временной интервал, с точностью 0,5 такта
процессора, который измеряет этот временной интервал ?

Да, утверждаю. Для нашего случая тактовая частота равна 1 МГц, так что точность будет 0.5 мкс. А в общем случае, полтакта процессора.

Вы собираетесь для этих целей использовать Analog Comparator ?
Тогда посмотрите Electrical Characteristic
параметр Analog Comparator Propogation Delay
Цитата
По поводу модернизации. Можно и для 1/16 сделать, только с дополнительными прибамбасами(:-(. Вы лучше скажите, что вы хотите сделать, тогда можно поконкретнее ответить.

С дополнительными прибамбасами я и сам знаю как, это была просто шутка biggrin.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Oct 20 2006, 02:23
Сообщение #99


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(=GM=)
Похоже вам слово системщик, как быку красная тряпка(:-), не обижайтесь.
Зачем обижаться. Почти верно. Только слово системщик у меня ассоциируется с чем-то сложным и за это уважаемым. Кстати, я сам системщик, то бишь системный программист. У вас же в последней проге слишком много ошибок или опечаток. Ну и ничего нового.

Интересно чем отличается конструкция {sei ; ret} от {iret} ? Если я не ошибаюсь, она только хуже.

Вообще, заинтриговало Ваше заявление про 0.5 такта.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 20 2006, 10:08
Сообщение #100


Ambidexter
*****

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



GetSmart У вас же в последней проге слишком много ошибок или опечаток. Ну и ничего нового.

Есть опечатки, строки 50, 51, 52 и 56, копи+пейст мой бич. Может и ошибки есть, как же без них(:-). Любая сколь угодно малая программа содержит хотя бы одну ошибку(:-). Кто сказал? Вирт?
Нового ничего, за исключением того, что прерывание таймера1 по переполнению не сбрасывается в данном прерывании, что есть правильно.

Вопрос в другом, как мерять импульсы и интервалы между ними от 1 мкс и выше? Есть предложения(:-)?

GetSmart Интересно чем отличается конструкция {sei ; ret} от {iret} ? Если я не ошибаюсь, она только хуже.

Это следствие смены детектора перехода (0-1 или 1-0), чтобы не портить установку. Я сам не очень уверен здесь, хотя делал всё по описанию. Обратите внимание на строчки 25, 26 и 52, 53.

GetSmart Вообще, заинтриговало Ваше заявление про 0.5 такта.

А меня Ваше про 400 Мбод. У меня максимум на 16-ти мегагерцовой атмеге - 39 Мбод.
Насчет 0.5 такта правда, на фирме посоветовался с электронщиком, вроде проходит.
Интересно, что defunct думает по поводу полтакта, пропал он куда-то...


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post

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

 


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


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