Написал программу частотомера, работающего по принципу обратного отсчета. (Пишу на ассемблере для tiny2313). В одной из частей этой программы выполняется следующее действие - включено прерывание по захвату Т/С1-м при приходе импульса из вне. Тоесть эти импульсы поступают на вход захвата постоянно, с одной и той же частотой - сигнал подаётся с кварцевого генератора. Ждем импульс. Импульс появился на входе захвата, срабатывает прерывание - запускается таймер приблизительно на 1 секунду. Все это время идет подсчет входных импульсов измеряемой частоты, подсчет переполнений Т/С1 который затактирован частотой Ф = 20МГц, подсчет переполнений Т/С0 (это таймер 1 секунды, но поскольку все тактируется кварцевым генератором 20 МГц, то нужно 77 переполнений Т/С0 при частоте счета Ф/1024). Когда прошло время приблизительно в 1 секунду опять ждем прерывания по захвату. Как только на входе захвата появляется входной импульс - срабатывает переполнение и всё выше сказанное останавливается. Дальше идет математика. Так вот сам вопрос - Если начинаем счем с прерывания захвату и заканчиваем им же, то число подсчитанных импульсов Т/С1 должно быть постоянно или равным, или отличатся на +/-1. У меня же эта разница постоянно колеблится от 0 до +/- более 100. Сама разница хаотична. Кто знает, подскажите, пожалуйста, верны ли мои ожидания, а если есть ошибка или недочет, то где именно их искать? Заранее очень благодарен!!!!!
Здравствуйте. Для повышения точности измерения этим методом делаю следующее -начальная загрузка числа 8 в TCNT1 для устранения ошибки, возникающей при первом срабатывании захвата -переполнения Т1 использую не только как старшую часть накопителя числа периодов импульсов Fclk, но и как формирователь интервала измерения (для частоты тактирования 20МГц и измерительном интервале ~1сек. будет 306 прерываний переполнения Т1) -для исключения потери 65536 периодов частоты тактирования при одновременном приходе последнего захвата и переполнения Т1 проверяю в прерывании захвата флаг переполнения и, при его наличии, обрабатываю этот флаг -при вычислении использую точное значение частоты генерации системы кварц-контроллер Для примера, посмотрите здесь http://radioded.ru/forum/viewtopic.php?p=1534#p1534
akl, спасибо Вам за ответ! У меня начало программы написано так - включаю Т/С1 с тактом Ф и включаю прерывание по захвату и ожидаю входного импульса. Когда пришел импульс по входу захвата срабатывает прерывание после которого начнется вся процедура описанная выше. В регистрах захвата содержиться значение Т/С1 на момент прихода первого "стартового" импульса. Это значение я сохраняю в отдельных регистрах, а потом, когда весь счет будет завершен, я вычитаю это значение из аналогичного, полученного в момент прихода последнего "финишного" импульса. Таким образом я получаю количество импульсов частоты fclk прошедших за время приблизительно равное 1 секунде и, теоретически, это количество должно быть постоянным если на входе измеряемая частота не меняется. Ваш вариант с +8 учту как заметку. На счет того чтобы интервал времени измерять с помощью Т/С0 - тоже учту. На счет исключения потерь периодов я сделал так - в интервале "старт" - "финишь" все срабатывания происходят по прерываниям - захват (для подсчета количества импульсов неизвестной частоты), переполнения Т/С0 (таймер ~1c.) и переполнения Т/С1 (счет количества импульсов fclk).
Можете объяснить или указать где почитать про "точное значение частоты генерации системы кварц-контроллер". Спасибо!!!!!
...Таким образом я получаю количество импульсов частоты fclk прошедших за время приблизительно равное 1 секунде и, теоретически, это количество должно быть постоянным если на входе измеряемая частота не меняется.
Не совсем так. Пример: измеряется частота Fx=77'777.777 Гц Fclk=19'998'753Гц за интервал времени 1 сек пройдет 77'777 периодов измеряемой частоты, но задача стоит в измерении Целого числа периодов поэтому программа должна дождаться прихода захвата последнего периода Fx, т.е. в счетчике Nx должно быть число 77'778, а в счетчике nx=19'998'810 Вычисляем Fx=19'998'753*77'778/19'998'810~77777,778Гц Допустим, что так получилось и требование прерывания захвата последнего измеряемого периода пришло в момент, когда TCNT1=FFFE. Естественно, в ICR1 оно аппаратно занеслось и войдя в прерывание по захвату, проанализировав, что это последний период счетчик nx останавливается. Но!!! Пока все это делалось был установлен флаг переполнения Т1. Если Ваша программа учитывает этот момент-отлично. Кстати, разговор был бы более предметным, если был бы Вы привели код на ассемблере.
"точное значение частоты генерации системы кварц-контроллер" определяю тестовой программой. Изначально программа формирует 10 секундный интервал в предположении, что Fclk=20'000'000Гц. Подаю этот интервал на частотомер-периодомер. Далее, по отклонению полученного периода от требуемых 10 секунд, получаю множитель, на который нужно умножить 20'000'000Гц, чтобы получить истинную Fclk.
Правильно, задача этого участка программы измерить целое число переодов Fx, процес подсчета периодов начинается по захвату и заканчивается по нему, а если в момент прихода импульса Fx случается переполнение Т/С1, то оно мне уже не нужно, захват был - он и обозначил финишь процедуры. Я эту ситуацию, сос значением FFFE в Т/С1 и сработкой захвата проверил на эмуляторе в AVRStudio - все работает.
Здравствуйте, благодарю за коррекцию моего текста программы! Вчера обнаружил один недочет в программе, исправлю его, посмотрю на результат. В противном случае буду "вгрызаться" в Ваш вариант обсуждаемой программы. И сразу есть вопрос - разве можно так сразу записывать
OUT TIFR,_FF ;!!!!!!!!!!
В книге написано что напрямую в регистры управления ничего не запишешь, нужно только посредством рабочего регистра общего назначения. Типа:
ldi temp, 0xFF; (или ser temp); out TIFR, temp;
Но Ваш вариант записи я попробую, если пойдет - экономия одна строка!
Все, работает!!!!! УРА-А-А-А-А!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Причина была в недодуманности в той части программы где Т/С1 уже молотит с частотой Ф, а Т/С0 - с Ф/1024 и идет ожидание входного импульса до момента переполнения Т/С0. Перед тем как разрешить прерывания я не сбрасывал флаги в TIFR. Теперь эта часть выглядит так:
ser temp; out TIFR, temp; sei;
Большое спасибо Вам за ответы! Также учту Ваши "программные приемы" на будущее! УДАЧИ!!!!!
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения