Представляю наработки по измерению длительности импульса и периода последовательности импульсов. Вообще, это довольно востребованная тема. В первую очередь на основании представленных наработок напрашивается реализовать частотомер, который в свою очередь, перерастает в массу устройств, как то: металлоискатели, измерители индуктивностей, ёмкостей, ESR, и пр. Кроме того сейчас в продаже имеются различные преобразователи (напряжение/ток/давление — частота), где представленные функции могут найти применение. Генератор импульсов я реализую на ATtiny2313. Быстренько набросаю исходник:

Контроллер тактирую от кварца 20 МГц (в принципе это не важно). ?спользую «неправильные» задержки стандартной библиотеки (имеется в виду «неправильные» в плане оптимальности реализации оных с помощью таймеров), однако для данного примера это совершенно не критично. Непосредственно измеритель реализую на ATmega128 kit — она у меня под рукой. Рассмотрим процесс измерения длительности импульса.
На верхнем осциллограмме синим цветом показан график зависимости значения счётного регистра TCNT1 от времени счёта (для удобства время я обозначил периодами переполнения OverflowC). Значение TCNT1 инкрементируется от нуля до максимального значения 65535 (чёрный пунктир), затем следует сброс в ноль и периодический повтор n раз (см. вершины «треугольников) . На нижней осциллограмме показан импульс длительностью Т, приходящий на вход захвата ICR1 счётчика T1 (PD4) с нашего вновь испечённого генератора (хотя можно подать с любого генератора). Сначала настраиваем прерывание по захвату по нарастающему фронту. По этому фронту запоминаем значение счётчика TCNT1 = EdgeR. Затем перестраиваем прерывание по захвату по ниспадающему фронту. По нему запоминаем значение TCNT1 = EdgeF. Между этими моментами времени могут произойти (если длительность импульса больше периода переполнения таймера 1) n переполнений таймера 1. Зная время переполнения таймера, а также длительность такта счёта tckl легко вычисляем значение длительности импульса по формуле:
Tpulse = EdgeF(tckl) — EdgeR(tckl) + 65536OverflowC(tckl);
или, упростив выражение:
Tpulse = tckl(EdgeF — EdgeR + 65536OverflowC);
Период последовательности импульсов измеряется так же
только прерывание по захвату настроено постоянно по нарастающему фронту.
Очевидно, что минимальная длительность импульса, которую сможет обработать данная реализация функции будет меньше времени выполнения действий в обработчике прерывания по захвату. Симуляция в AVRStudio отмеряла 49 тактов, т.е для 8 МГц — это 6,12 мкс, что и подтверждается практикой — минимальное значение длительности импульса, которое правильно вычисляется — 7 мкс (см. фото).

Если сделать измеритель на контроллере с частотой 20 МГц (максимальная для AVR mega), то минимальная обрабатываемая длительность будет уже 2,45 мкс, т.к такт — 50 нс * 49 = 2,45 мкс. Но это цифры для ДАННОЙ реализации — на ассемблере будет, конечно немного лучше. Если необходимо измерять меньшие временные интервалы, нужно воспользоваться внешними управляемыми делителями. Но это уже другая история.
В архиве исходник. Понятное дело, что исходник нужно править в зависимости от поставленных задач.

а дальше?
Что «дальше»?
продолжение б хотелось — например частотомер, измеритель индуктивности
Не всё сразу 🙂 Процесс идёт.
Написано «Период последовательности импульсов изменяется так же»
А разве период изменяется?
🙂 ?змеряется, конечно. Очепятка получилась — уже исправил.
Опять одна и та же, кочующая с одного сайта на другой, ошибка. Вес переменной OverflowC равен 65536!
Tpulse = tckl(|EdgeF — EdgeR| + 65536OverflowC) — более строгое выражение
«…минимальная длительность импульса, которую сможет обработать данная реализация функции будет меньше??? (больше!!!) времени выполнения действий в обработчике прерывания по захвату.» ?звините.
Здравствуйте гость!
1. Материалы моего сайта ни с какого сайта не скопипащены — всё пишу сам. Если на что-то ссылаюсь, то обязательно указываю.
2. В данной статье основой примера послужили материалы книги автора Ю.А. Шпак «Программирование на языке Си AVR и PIC микроконтроллеров». стр. 168
3. Насчёт веса 65536 согласен — провтыкал (((.
4. Насчёт «минимальной длительности…» хорошенько подумайте и поймёте, что Вы ошиблись.
5. ?звиняться не нужно — одно дело делаем)))
Удачи, коллега!
Здравствуйте.
1,2. Виноват, нечетко выразился. ?мелось ввиду, что эта ошибка (65535 вместо 65536, а также 255 вместо 256) слишком распространенная.
4. «хорошенько подумайте и поймёте, что Вы ошиблись.» Возвращаю.
Удачи, коллега!
не работает измеритель периода. и вообще вы учли что EdgeF<EdgeR а наоборот видимо нет… а при выводе на дисплей этих значений они постоянно плывут,а должны изменяться только при захватах по нар.фронту как тут задумано,и почему то разница между ними постоянно одинакова
Почему обязательно EdgeF < EdgeR ? Оно может быть и меньше, и больше, и равно. Просто если так будет, то добавка к произведению будет отрицательная, т.е вычитание. Мне трудно так, навскидку, сказать, почему у Вас не работает. Ещё раз посмотрите внимательно исходник и монтаж. Схема и прошивка неоднократно проверены - непроверенных мною конструкций я сайт не выкладываю.
А зачем в выражении
PulseClocks = ((unsigned long)EdgeF - (unsigned long)EdgeR + ((unsigned long)OverflowC <>3;//вычисляем длительность импульса
Все переменные умножаются на unsigned long
Это называется «приведение типов». Почитайте в любом учебнике по Си. Удачи!
Разницу EdgeF — EdgeR же нужно брать по модулю abs(EdgeF — EdgeR), иначе формула врет когда EdgeR > EdgeF
поправка к предыдущему комментарию — …когда EdgeF > EdgeR
Если F > R , то поправка положительная. Если наоборот — отрицательная.
пардон, сам напутал )))