1891ВМ12Я 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Здравствуйте! Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба C точностью до микросекунды с кварцем на 1Мгц никак. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо? А считывать значения периода с разрешением 1мкс при тактовой 1МГц он будет успевать? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба C точностью до микросекунды с кварцем на 1Мгц никак. А я бы сказал - элементарно, но на AVR. Для PIC не знаю точно, есть у них функция захвата и есть ли делитель у таймера? То есть инкрементируется таймер от 1 МГц или от делителя 1/4 или ещё как. Если от 1 МГц и есть захват, то этого достаточно. Ну и интервал не должен быть очень маленьким. Внутри него должно успеть обработаться прерывание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 2 июня, 2006 Опубликовано 2 июня, 2006 (изменено) · Жалоба А инкрементировать ещё одни (старшие) 16 бит по переполнению таймера вам слабо?Можно подробнее чуточку? Какие старшие 16 бит? Подскажите, пожалуйста, как это можно сделать? Я пытался реализовать это так: По внешнему прерыванию ставлю таймер в режим сравнения на 50К (+обнуление по переполнению) и по прерыванию увеличиваю значение 32-битной переменной в ОЗУ на эти самые 50к. После ещё одного внешнего прерывания останавливаю таймер и остаток (содержимое TCNTn) добавляю к этой же переменной (после чего обнуляю TCNTn). Но: в результате, хоть я и подаю на вход импульсы постоянной длительности, значения на выходе пляшут как будет бы у меня генератор случайных чисел =( Изменено 2 июня, 2006 пользователем AVR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Чё-то я ослеп. Речь как раз об AVR. Берёте Мегу8, она с захватом. Всё получится с точностью 1 мкс, если интервалы будут хотя бы 10 и более мкс. Это если писать на асме. Если на си, то раза в 3 большие интервалы. Вроде бы правильно делаете. Может какая мелкая ошибка. Прикрепите исходник, я посмотрю. Кстати, когда обнуляете таймер, обнуляете ещё переменную? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Чё-то я ослеп. Речь как раз об 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Нельзя выйти на точность в 1мкс в случае когда прерывание таймера "по захвату" сработает одновременно с прерыванием таймера "по переполнению" либо по "сравнению" для увеличения старшей части 32-х битного счетчика времени. Ну почему же? Захват же аппаратный. Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению. А если захват аппаратный и прерывание по переполнению, то таймер никогда не останавливается и "захватывается" точное значение. Поэтому я бы рекомендовал делать прерывание именно по переполнению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Немного дополнительных проверок в коде могут отличить в какой момент сработал захват если он сработал рядом (чуть раньше, чуть позже) с прерыванием по переполнению. Да все так, доп проверка для ((ICR > 0) и (ICR < длительность обработчика OVF)) Все равно есть ситуации где точность 1mks на двух прерываниях обеспечить не реально. Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет? А бог его знает. Если CAPT сработал в момент перехода на обработку OVF - то было, если раньше - то не было. А теряется не много ни мало всего лишь 64k mks ;> т.е. думаю нужно вводить еще прерывание OC, с OCR = 64k/2, чтобы точно знать о природе ICR=0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет? Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Ну представьте захвачен ICR = 0. Что делать? Было отработано прерывание по переполнению или нет? Да ладно Вам! Для этого нужно прочитать TIFR и понять обработалось уже прерывание по переполнению или нет. Действительно :a14: "А ларчик то просто открывался" :) (подправил код примера с учетом Вашего последнего поста.) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Надо только в прерывании захвата смотреть, если число маленькое (<100) то проверять TIFR, а если большое, то не проверять. Иначе тоже может сглючить. Там это учтено: tst r1 brne ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 2 июня, 2006 Опубликовано 2 июня, 2006 · Жалоба Там это учтено: Да, я это написал когда ещё не было. Кстати, 16 бит таймера и 8 старших бит счётчика в регистре дадут уже период в 16 секунд. Может этого будет достаточно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться