Счетчик импульсов своими руками схемы. Простой счётчик числа оборотов - Конструкции простой сложности - Схемы для начинающих

💖 Нравится? Поделись с друзьями ссылкой

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

Рис. 172. Пересчетная декада

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

Одна декада счетчика-секундомера показана на рисунке 172. Она состоит из двоично-десятичного счетчика на дешифратора на и индикатора на неоновой лампе Для питания индикатора нужно высокое напряжение , поэтому по правилам техники безопасности прибором должен пользоваться руководитель. В схеме используется дешифратор, специально предназначенный для работы с высоковольтным индикатором. Вместо лампы можно использовать лампы других типов: рассчитанные на напряжение питания 200 В и силу тока индикации Микросхема состоит из триггера со счетным входом (вход и триггерного делителя на 5 (вход При соединении выхода счетного триггера (выхрд 1) с входом делителя образуется двоично-десятичный счетчик. Он реагирует на задний фронт положительного импульса или на отрицательный скачок напряжения, поданного на вход . В условных обозначениях счетный фронт иногда показывается в виде стрелки, направленной к Микросхеме, если она реагирует на положительный скачок напряжения, или стрелки, направленной от микросхемы, если она реагирует на отрицательный перепад напряжения.

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

устанавливается в нулевое состояние кнопкой «Уст. О», при этом на входы счетчика подается логическая 1. Затем переключателем выбирается источник счетных импульсов - им может быть или триггер, или мультивибратор. В режиме «счет механических замыканий» при последовательном нажатии и отпускании кнопки происходит двоично-десятичный счет и на индикаторе последовательно загораются цифры 1, 2, 3 и т. д. до цифры 9, затем загорается цифра 0 и счет повторяется. В режиме счета импульсов на вход счетчика поступают импульсы мультивибратора, собранного по уже известной схеме на рис. 168). Для измерения времени в секундах частота импульсов должна равняться 1 Гц. Она устанавливается переменным резистором и емкостью равной

Для получения многоразрядного двоично-десятичного счетчика включаются последовательно, т.е. выход первого соединяется со входом второго, выход второго соединяется со входом третьего и т. д. Для установки многоразрядного счетчика в нулевое состояние входы объединяются и подключаются к кнопке «Уст. 0».

Если, например, прибор предполагается использовать на уроках физики, то время нужно измерять в довольно широком диапазоне - от 0,001 до 100 с. Для этого генератор должен иметь частоту а счетчик должен состоять из пяти десятичных разрядов. При этом показания цифрового индикатора будут иметь следующий вид: 00,000; 00,001; 00,002 и т.д. до 99,999 с.

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

Можно привести также другие примеры использования электронных счетчиков. Например, автомат, моделирующий игру «в кости», состоит уже рассмотренной декады на

И неоновой лампы управляемой импульсами мультивибратора (см. рис. 168, 172). Игроки поочередно нажимают кнопку прерывающую счет. Выигрывает тот, у кого индикатор покажет большее число. Момент остановки счетчика, как и момент остановки подбрасываемого кубика с точками от 1 до 6, определяется случайными причинами, поэтому счетная декада вместе с мультивибратором являются электронным датчиком случайных чисел. Приведем еще примеры ее использования в различных игровых ситуациях.

При проверке скорости реакции игроков резистором устанавливается определенная частота работы мультивибратора и скорость смены цифр индикатора (см. рис. 168 и 172). Участникам игры предлагается нажимать на кнопку мультивибратора каждый раз, как индикатор покажет определенную, заранее выбранную цифру. Выполнить поставленное условие тем сложнее, чем выше частота переключения. Первыми выбывают из игры наиболее медлительные, победителем становится игрок, обла дающий лучшей реакцией. В другом, более сложном варианте игры нужно продолжать нажатия кнопки в установленном судьей темпе после того, как исчезают показания индикатора. Для этого его закрывают механической шторкой или отключают кнопкой

Счетную декаду вместе с мультивибратором особенно удобно использовать в играх, если ее питание сделать автономным, т. е. не связанным с сетью. В этом случае используют семисегментный светодиодный индикатор управляемый дешифратором интегральной схемы . С этой микросхемой и индикатором мы уже знакомы (рис. 150, 163). Схемы мультивибратора и счетчика остаются неизменными. Схема датчика случайных чисел, работающего от источника с напряжением 5 В, показана на рисунке 173.

Примером более сложного устройства, работающего на основе электрического счетчика, является блок выдержки времени, или таймер. На рисунке 174 показана принципиальная схема таймера, позволяющего включать различную нагрузку на время от 0 до 999 с. Он состоит из трехразрядного десятичного счетчика, собранного на микросхеме трех дешифраторов на микросхеме мультивибратора и схемы управления на микросхеме а также микросхеме Источником счетных импульсов является мультивибратор, настроенный на частоту 1 Гц. Его импульсы подаются на вход трехразрядного десятичного счетчика. Двоичные коды с каждого разряда подаются на дешифраторы На их выходах последовательно пояезляются нулевые сигналы по мере поступления на входы

Рис. 173. Пересчетная декада со светодиодным индикатором

соответствующих двоичных кодов. Установка нужной выдержки времени осуществляется переключателями соединяющими выходы дешифраторов с элементами микросхемы Входы элементов И попарно соединены для получения элемента Переключателем устанавливаются единицы секунд, переключателем десятки секунд и переключателем сотни секунд. Если, например, переключатели соединяются с выводами 2, 3 и 7 дешифраторов, то на входах элемента ИЛИ-НЕ будут три 0 только в момент, когда счетчик зафиксирует 237 импульсов или пройдет промежуток времени, равный 237 секундам с момента начала счета. При этом на выходе элемента ИЛИ-НЕ появится сигнал 1. До этого момента при всех двоичных кодах счетчика на выходе логического элемента был нулевой сигнал.

Схема управления таймера работает следующим образом. Предварительно нажимается кнопка «Стоп», в результате RS-триггер, собранный по микросхеме устанавливается в нулевое состояние. С прямого выхода нулевой уровень напряжения подается на транзистор 1/77, в эмиттерную цепь которого включена обмотка электромагнитного реле. Транзистор и реле находятся в выключенном состоянии. Одновременно с этим на инверсном выходе 6 появляется высокий уровень, который служит сигналом сброса для счетчика. При нажатии кнопки «Пуск» RS-триггер переходит в единичное состояние, на прямом выходе 3 появляется. высокий уровень напряжения, достаточный для открывания транзистора 1/77 и срабатывания реле. Его контакты замыкают цепь питания нагрузки. Одновременно с этим

(кликните для просмотра скана)

нулевой уровень напряжения, снимаемый с инверсного выхода триггера, «открывает» счетчик. Счетчик работает до тех пор, пока на выходах дешифратора не появятся выходные сигналы, соответствующие набранному числу. В. этом случае, как уже говорилось, на выходе возникает единичный сигнал, который через инвертер подается на вход -триггера. Происходит его установка в нулевое состояние и, соответственно, выключение транзистора, электромагнитного реле и нагрузки. Счетчик устанавливается в нулевое состояние.

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

-20 dB писал:
А почему не подойти к делу малой кровью? Если есть что-то вроде уже упомянутого выше ИЖЦ5-4/8, с раздельными выводами сегментов?

В заначках с советских времён неиспользуемых К176ИЕ4 осталось море (счетчик/делитель на 10 с семисегментным дешифратором и выходом переноса, использовался для формирования единиц минут и часов в электронных часах, неполный аналог - CD4026 - в чём неполнота, не смотрел... пока) в классическом включении для управления ЖК. 4 шт - по 2 на канал, + 2 шт. 176(561)ЛЕ5 или ЛА7 - одна для формирователей одиночных импульсов (подавителей дребезга контактов), вторая - для формирования меандра для "засветки" ЖК индикатора?

Конечно, на МП решение красивее, но на мусоре - дешевле, и решается исключительно на коленке... С программированием МП, например, у меня туго (если только готовый дамп кто-то подсуетит) - мне с железяками проще.


Ну вот тут я готов поспорить. Давайте посчитаем. Для начала стоимость:
1. PIC12LF629 (SOIC-8) - 40руб. (~1,15$)
2. Дисплей от Моторола С200/С205/Т190/Т191 - около 90руб (~2.57$) Кроме того разрешение 98х64 - рисуй и пиши чо хочешь.
3. Рассыпуха (SMD-резюки, кнопочки, SMD-конденсаторы и прочее) на вскидку - около 50руб. (~1,42$)

Итого: ~180руб (~5$)

Корпус, аккум (я бы выбрал Lo-Pol акк от той же моторолки С200 - компактно, ёмко, недорого (сравнительно)) - не считаем, так как и то и другое нужно в обоих вариантах.

Теперь Ваш вариант:

1. ИЖЦ5-4/8 - около 50руб (~1.42$)
2. К176ИЕ4 (CD4026) - 15руб (~0,42$)x4=60руб(~1.68$)
3. К176ЛА7 - 5руб (~0,14$)x4=20руб(~0.56$)
4. Рассыпуха (SMD-резюки, кнопочки, SMD-конденсаторы и прочее) на вскидку - около 50руб. (~1,42$)

Итого: ~180руб(~5$)

В чём выгода?

Теперь прикинем ТТХ и функционал:

У варианта с МК поторебление будет максимум 20мА, в то время как в Вашем варианте, я думаю раза в 1,5...2 больше. Кроме того в Вашем варианте - сложность (относительная) печатной платы на 7 корпусах+многогогая ИЖЦ5-4/8 (наверняк - двусторонняя), невозможность модернизировать устройство (добавить или изменить функционал) не влезая в схему (только на программном уровне), отсутствие возможности организовать память на измерения (счёт), питание не менее 5В (с меньшего Вы не раскачаете ИЖЦ), вес и габариты. Можно много ещё привести доводов. Теперь вариант с МК. Про ток потребления уже написал - 20мА макс. + возможность спящего режима (потребление - 1...5 мА (в основном - LCD)), сложность платы для одной 8-ногой микросхемы и 5 выводного разъёмчика для мотороловского LCD - смешно даже говорить. Гибкость (можно программно, без изменения схемы и платы наворотить такого - волосы дыбом встанут), информативность графического 98х64 дисплея - ни в какое сравнение с 4,5 разрядами 7-сегментного ИЖЦ. питание - 3...3,5В (можно даже таблеточку CR2032, но лучше всё таки Li-Pol от мабылы). Возможность организации многоячейной памяти на результаты измерений (счёта) прибора - опять таки только на программном уровне без вмешательства в схему и плату. Ну и наконец - габариты и вес ни в какое сравнение с Вашим вариантом. Аргумент - "я не умею программировать" не принимется - кто хочет, тот найдёт выход. Я до вчерашнего дня не умел работать с дисплеем от мобильника Моторола С205. Теперь умею. Прошли сутки. Потому что мне это НАДО. В конце концов Вы правы - можно кого нибудь и попросить.)) Вот примерно так. И не в красоте дело, а в том, что дискретная логика безнадёжно устарела как морально так и технически в качестве основного элемента схемотехники. То, для чего требовались десятки корпусов с диким общим потреблением, сложностью ПП и огромными габаритами, теперь можно собрать а 28-40 ногом МК легко и непринуждённо - поверьте мне. Сейчас даже инфы по МК гораздо больше чем по дискретной логике - и это вполне объяснимо.

Счётчик на микроконтроллере довольно прост для повторения и собран на популярном МК PIC16F628A с выводом индикации на 4 семисегментных светодиодных индикатора. Счётчик имеет два входа управления: «+1» и «-1», а также кнопку «Reset». Управление схемой нового счётчика реализовано таким образом, что как бы долго или коротко не была нажата кнопка входа, счёт продолжится только при её отпускании и очередном нажатии. Максимальное количество поступивших импульсов и соответственно показания АЛС - 9999. При управлении на входе «-1» счёт ведётся в обратном порядке до значения 0000. Показания счётчика сохраняются в памяти контроллера и при отключении питания, что сохранит данные при случайных перебоях питающего напряжения сети.

Принципиальная схема реверсивного счётчика на микроконтроллере PIC16F628A:

Сброс показаний счётчика и одновременно состояния памяти в 0, осуществляется кнопкой «Reset». Следует помнить, что при первом включении реверсивного счётчика на микроконтроллере, на индикаторе АЛС может высветиться непредсказуемая информация. Но при первом же нажатии на любую из кнопок информация нормализируется. Где и как можно использовать эту схему - зависит от конкретных нужд, например установить в магазин или офис для подсчёта посетителей или как индикатор намоточного станка. В общем думаю, что этот счётчик на микроконтроллере кому-нибудь принесёт пользу.

Если у кого-то под рукой не окажется нужного индикатора АЛС, а будет какой-нибудь другой (или даже 4 отдельных одинаковых индикатора), я готов помочь перерисовать печатку и переделать прошивку. В архиве на форуме схема, плата и прошивки под индикаторы с общим анодом и общим катодом. Печатная плата показана на рисунке ниже:

Имеется также новая версия прошивки для счётчика на микроконтроллере PIC16F628A. при этом схема и плата счётчика остались прежними, но поменялось назначение кнопок: кнопка 1 - вход импульсов (например, от геркона), 2 кнопка включает счёт на вычитание входных импульсов, при этом на индикаторе светится самая левая точка, 3 кнопка - сложение импульсов - светится самая правая точка. Кнопка 4 - сброс. В таком варианте схему счётчика на микроконтроллере можно легко применить на намоточном станке. Только перед намоткой или отмоткой витков нужно сначала нажать кнопку "+" или "-". Питается счётчик от стабилизированного источника напряжением 5В и током 50мА. При необходимости можно питать от батареек. Корпус зависит от ваших вкусов и возможностей. Схему предоставил - Samopalkin

Счетчики электрических импульсов

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

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

Счетчики электрических импульсов имеются как в ТТЛ, так и в КМОП сериях. В качестве примера счетчика ТТЛ рассмотрим микросхему К155ИЕ5. Функциональная схема счетчика К155ИЕ5 приведена на рисунке 1.51,а, а его условное обозначение на принципиальных схемах на рисунке 1.51,б. Счетчик К155ИЕ5 имеет фактически два счетчика: с коэффициентом пересчета два (вход С0 и выход Q 0) и с коэффициентом пересчета восемь (вход С1 и выходы Q 1, Q 2, Q 3). Счетчик с коэффициентом пересчета шестнадцать легко получается, если соединить выход Q 0 с входом С1, а импульсы подавать на вход С0. Временная диаграмма работы такого счетчика приведена на рисунке 1.52.

На рисунке 1.53 приведены схемы подключения, изменяющие коэффициент пересчета счетчика К155ИЕ5. Выходы счетчика Q 0, Q 1, Q 2, Q 3 имеют соответственно весовые коэффициенты 1, 2, 4, 8. Соединив выходы Q 1, Q 2 с входами установки счетчика в нуль, получим счетчик с коэффициентом пересчета шесть (рис. 1.53,а). На рисунке 1.53,б показана схема подключения для получения коэффициента пересчета десять, а на рисунке 1.53,в – двенадцать. Однако в схемах, приведенных на рисунках 1.53,а – в, отсутствует возможность установки счетчиков в нулевое состояние.

На рисунках 1.54,а, б приведены соответственно счетчики с коэффициентами пересчета шесть и семь, в которых предусмотрен вход установки счетчика в нулевое состояние. Анализ работы схем, приведенных на рисунках 1.53 – 1.54, показывает, что для получения заданного коэффициента пересчета соединяют с входами логического элемента И те выходы счетчика, весовые коэффициенты которых в сумме дают необходимый коэффициент пересчета.

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

Рассмотрим некоторые из счетчиков КМОП серии. На рисунке 1.55 приведено условное обозначение микросхемы К561ИЕ8 – десятичного счетчика с дешифратором. Микросхема имеет вход установки в нулевое состояние R , вход для подачи счетных импульсов положительной полярности CP и вход для подачи счетных импульсов отрицательной полярности CN .

Переключение счетчика происходит по спадам импульсов положительной полярности на входе CP , при этом на входе CN должна быть логическая единица. Переключение счетчика будет происходить по спадам импульсов отрицательной полярности на входе CN , если на входе CP логический нуль. На одном из десяти выходов счетчика всегда присутствует логическая единица. Установка счетчика в нуль происходит при подаче на вход R логической единицы. При установке счетчика в нулевое состояние на выходе «0» установится логическая единица, а на всех остальных выходах – логические нули. Микросхемы К561ИЕ8 можно объединять в многоразрядные счетчики с последовательным переносом, соединяя выход переноса предыдущей микросхемы с входом CN последующей. На рисунке 1.56 приведена схема многоразрядного счетчика на микросхемах К561ИЕ10.

Промышленностью выпускаются счетчики для электронных часов. Рассмотрим некоторые из них. На рисунке 1.57 приведено условное обозначение микросхемы К176ИЕ3, а на рисунке 1.58 – микросхемы К176ИЕ4. На этих рисунках выходы микросхем показаны для стандартного обозначения сегментов индикатора, приведенного на рисунке 1.59. Эти микросхемы отличаются друг от друга коэффициентом пересчета. Коэффициент пересчета микросхемы К176ИЕ3 равен шести, а коэффициент пересчета микросхемы К176ИЕ4 равен десяти. Установка в нуль рассматриваемых счетчиков осуществляется подачей сигнала логической единицы на вход R . Переключение триггеров счетчика происходит по спаду положительных импульсов на входе С. Микросхемы имеют выход переноса р (вывод 2), к которому подключается обычно вход следующего счетчика. Спад напряжения на этом выходе формируется в момент перехода счетчика из состояния 9 в состояние 0. Микросхемы различаются сигналами на выводе 3. Для микросхемы К176ИЕ3 на выводе 3 появляется логическая единица при установке счетчика в состояние 2, а для микросхемы К176ИЕ4 – в состояние 4. Это необходимо для обнуления показаний часов в 24 часа.

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

На рисунке 1.60 приведена схема подключения люминесцентного индикатора к выходам микросхемы К176ИЕ4. Подключение индикатора к выходам микросхемы К176ИЕ3 будет аналогичным.

Схемы подключения светодиодных индикаторов к выходам микросхемы 176ИЕ4 приведены на рисунках 1.61,а и 1.61,б. На входе S устанавливается логический нуль для индикаторов с общим катодом и логическая единица для индикаторов с общим анодом.

Описание микросхем К176ИЕ5, К176ИЕ12, К176ИЕ13, К176ИЕ17, К176ИЕ18, К176ИД2, К176ИД3 и их применение в электронных часах можно найти в . Микросхемы К176ИЕ12, К176ИЕ13, К176ИЕ17, К176ИЕ18 допускают напряжение питания от 3 до 15 В.

Часто при работе микроконтроллерного устройства есть необходимость отсчитывать «антропоморфное» время – сколько долей секунды светиться светодиоду, максимальный промежуток времени double-click и т. д. В общем, отсчитывать не только нано- и микросекунды, но и десятки миллисекунд, а то и секунды, минуты и даже часы (боюсь сказать о сутках…).
В то же время в микроконтроллерах нередко нужно одновременно с этим иметь дело с микросекундами – периоды импульсов, антидребезговое ожидание и т. п.
Есть также устройства, которые работают непрерывно многие часы и даже сутки – авиационная техника, автомобильная, скважинные устройства (там речь идет иной раз о непрерывной работе несколько дней). В этих случаях недопустимо переполнение таймеров и 8-битных переменных.
Хотелось бы это все объединить в одно изящное и универсальное решение – иметь средство измерения времени с точностью до микросекунды, не переполняющееся несколько дней.
Почему бы и нет? Помучился я некоторое время и родил решение для 8-битных микроконтроллеров AVR. Для этого я задействовал 8-битный таймер-счетчик и 4х-байтную переменную. С PIC-ами и AT89 я сейчас не работаю, а с другими embedded-платформами не дружу. Впрочем, если читатели помогут – сделаю и для них.
Достоинства – код в высшей степени повторяемый (я уже 5-ое устройство с ним делаю); простота в работе (не используются прерывания для клиентской части работы); клиентская часть кода условно платформенно-независимая; в прерывании – одна операция суммирования (но, правда, для 4-хбайтной величины); нет внешнего устройства - таймера реального времени.
Недостаток я нашел один – занят один такой полезный и всегда нужный таймер…
Статья будет интересна в первую очередь начинающим - Америку я тут не открыл.

Теория

Итак, я имею в своем распоряжении устройство на основе Atmega16A с кварцем 12MHz. Берем его таймер-счетчик 0. Это восьмиразрядный таймер – нам и хватит. Почему? Считаем:
  1. берем 12 MHz от кварца и берем коэффициент деления на 8 – получаем частоту 1500 KHz;
  2. берем режим CTC (сброс при совпадении) и ставим прерывание на совпадение с 150 – получаем частоту срабатывания прерывания 10 KHz;
  3. на этом самом прерывании инкрементируем переменную (получается инкремент каждые 0.1 миллисекунды);
  4. если это беззнаковая 32х-битная величина, то она переполнится приблизительно после
    • 429496729.6 миллисекунд;
    • 42949.7 секунд;
    • 7158.3 минут;
    • 119.3 часов;
    • 4.97 суток.
Другими словами, такое решение мне создает таймер с точностью до 0.1 миллисекунды на (почти) 5 суток (надо тут, правда, учитывать, что реальные кварцы имеют погрешность - об это далее). А если еще анализировать значение собственно таймера 0 – он инкрементируется каждые 2/3 микросекунды – то можно получит счетчик с точностью до 0.67 микросекунды.
Хватит? Мне – за глаза. Используя счетчик по 0.1 миллисекунды, я в своих проектах:
  • считаю длительности свечения и пауз между ними светодиодов;
  • учитываю timeouts при работе с UART, USB;
  • задаю всевозможные ситуации в тестовом оборудовании – сложные пространственно-временнЫе комбинации;
  • выдерживаю заданные промежутки времени при опросе АЦП и прочих датчиков;
  • сообщаю компьютеру время своей (устройства) работы и с заданным интервалом времени передаю информацию;
  • с учетом счетчика до микросекунды я осуществляю антидребезговый контроль при нажатии клавиш, анализ импульсов в протяженных линиях.
И все это спокойно влазит В ОДИН КОНТРОЛЛЕР ATmega16! Причем это не Ассемблер, а межплатформенный Си! И никакого внешнего счетчика реального времени!
Неплохо, да?

Настройка для AVR

Как это все сделать в AVR?
Прежде всего, заводим внешнюю переменную, которую я называю «ДециМиллиСекунда»:
// в main.h typedef unsigned long dword; // беззнаковое 32х-битное целое extern volatile dword dmsec; // 0.1msec // в main.c volatile dword dmsec;
Как верно подметил @no-smoking, эта переменная должна быть volatile, чтобы ее компилятор не попытался оптимизировать.
Инициализацию этой переменной я делаю в функции:
dmsec = 0;
Далее я задаю режим работы таймера 0:
// . таймер 0 – 0.1msec Timer0_Mode (TIMER_Mode_CTC | TIMER0_Clk_8); Timer0_Cntr (149); Timer_Int (Timer0_Cmp);
При этом в каком-нибудь MCU_init.h объявляю все, что надо:
// в mcu_init.h #include // . TIMSK #define Timer0_Cmp (1 << 1) // совпадение таймера 0 // . TCCRn #define WGM1 (1 << 3) #define CS1 (1 << 1) // . источник сигнала для таймера 0 #define TIMER0_Clk_8 CS1 // предделитель 8 // . режим работы таймера #define TIMER_Mode_CTC WGM1 // CTC (сброс при совпадении) // . настройка таймера #define Timer_Int(Mode) TIMSK = (Mode) #define Timer0_Mode(Mode) TCCR0 = (Mode) #define Timer0_Cntr(Cntr) OCR0 = (Cntr)
Ну и далее, когда можно, разрешаю прерывания:
#asm ("SEI")
Осталось описать прерывание. Это проще, чем все предыдущее:
#include interrupt Timer0_Compare (void) { ++dmsec; }
Все, таймер описан, настроен и запущен!

Настройка для PIC

Вот что мне подсказали уважаемые PICоманы:

На пиках это легко повторяется при помощи модуля Timer2. Именно в нем есть аналогичная функция прерывания по совпадению.

PR2 = 75 - значение, при котором таймер обнулится и сгенерирует прерывание
T2CON.T2CKPS = 2 - прескалер 1:16
T2CON.T2OUTPS = 0 - без постскалера
T2CON.TMR2ON = on - таймер включен

IPR1.TMR2IP = 1 --высокоприоритетное прерывание
PIR1.TMR2IF = off --сбрасываем флаг прерывания
PIE1.TMR2IE = on --включаем прерывание по совпадению TMR2 и PR2
INTCON.GIE = on --включаем обработку прерываний

Как видно, прескалер тут в 2 раза больше, потому PR2 в 2 раза меньше.
Данные настройки будут генерировать прерывания с частотой 10 kHz при системной частоте в 48 MHz (на таймер идет Fosc/4) - стандартная частота для USB Full Speed.

Использование

Код для клиента этого таймера получается кросс-платформенным (если не считать обращения к значению таймера 0 в AVR).
Вот фрагмент кода обмена по USB:
#include "main.h" // тут переменная dmsec, next_USB_timeout #include "FT245R.h" // тут функции работы с модулем USB #include "..\Protocol.h" // тут протокол обмена микроконтроллер - компьютер // ** // ** Анализ пакетов по USB // ** void AnalyzeUSB (void) { #define RECEIVE_BYTE(B) while (!FT245R_IsToRead)\ { if (dmsec > end_analyze) return; }\ B = FT245_ReadByte (); #define RECEIVE_WORD(W) // аналогично для 2х байт #define RECEIVE_DWORD(W) // аналогично для 4х байт dword end_analyze, d; NewAnalyze: if (!FT245R_IsToRead) // нет пакетов? return; end_analyze = dmsec + max_USB_timeout; // timeout для текущего анализа next_USB_timeout = dmsec + MaxSilence_PC_DEV; // timeout для общего обмена RECEIVE_BYTE (b) // заголовок пакета switch (b) { case SetFullState: RECEIVE_DWORD (d); // читаем слово is_initialized = 1; // обрабатываем ChangeIndicator (); break; } // switch (pack) goto NewAnalyze; #undef RECEIVE_BYTE // отменяем #define #undef RECEIVE_WORD #undef RECEIVE_DWORD }
Макрофункции RECEIVE_BYTE, RECEIVE_WORD, RECEIVE_DWORD реализуют процедуры чтения с учетом timeout для данной фазы обмена. В итоге, если чего зависло на другой стороне, то микроконтроллер не впадет в «спячку». Обратите внимание – WatchDog не понадобился! И все благодаря переменной/константе max_USB_timeout, которая задает timeout с точностью до 0.1 миллисекунды.
Точно также реализуется анализ «тишины в эфире» переменной next_USB_timeout. Это позволяет микроконтроллеру 1) узнать, что компьютер куда-то исчез, 2) как-то об этом сигнализировать (в моем случае загорается светодиод «ошибка»). Константа/переменная MaxSilence_PC_DEV позволяет варьировать понятие «тишины» в широчайших пределах – от доли миллисекунды до нескольких суток.
Аналогично реализуются все остальные моменты.
Если же вам нужно использовать счетчик микросекунд, то там появляется функция сравнения:
#define GetUSec(A,B) { #asm ("CLI"); A = dmsec; B = TCNT0; #asm ("SEI"); } // ** // ** Разница во времени между событиями с точностью до 2/3usec // ** dword Difference (dword prev_dmsec, byte prev_usec) { dword cur_dmsec; byte cur_usec; dword dif; // . засекаем текущее время GetUSec (cur_dmsec, cur_usec); // вычисляем разницу dif = cur_dmsec - prev_dmsec; dif <<= 8; if (cur_usec < prev_usec) dif += 255 + (dword) cur_usec - prev_usec; else dif += cur_usec - prev_usec; return dif; }
Функции передается предыдущий момент времени – предыдущее значение dmsec и таймера 0.
Вначале мы макросом GetUSec останавливаем прерывания, чтобы в момент копирования не испортилось значение dmsec и счетчика. И копируем текущее время.
Далее мы приводим разницу во времени к формату 2/3 микросекунды с учетом переполнения.
Ну и возвращаем это время.
А далее мы это используем в обычном if для контроля антидребезга и прочих мероприятий. Только не забудьте также приостановить прерывания при засекании текущего момента времени – а лучше используйте макрос GetUSec.

Результаты

Этот таймер оказался для меня в высшей степени удобным решением. Думаю, он и вам пригодится. А применил я его в следующих своих проектах:
  • Коммутатор фехтовальных ситуаций . Это здоровенная плата пол на пол метра с тремя контроллерами - ATmega128 как центральный и ATmega64 как два вспомогательных (правая и левая стороны). Между тремя контроллерами и их компонентами нет гальванической связи - питание на основе ионисторов, связь через опторазвязки. Центральный контроллер заряжает группы одних ионисторов и питает в это время обе стороны от других ионисторов. Тут пришлось сделать многоступенчатый алгоритм коммутации всего этого с тем, чтобы минимизировать взаимосвязь. В частности, речь идет о слаженной работе 8 реле - тут работают таймеры на 3.3мсек (гарантированное время срабатывания реле). Ну и, собственно, обе стороны управляют 10 реле и еше с пол сотни мультиплексоров. Все это хозяйство работает с четко заданными временнЫми характеристиками (с точностью до 1 мсек, максимальные длительности - 6 секунд). Ну и, в конце концов, банальные timeout для USB, UART.
  • Датчик глубины . Здесь я решаю другую задачу (проект в работе). Имеются два проводника (многометровые), задающие ситуацию «сдвиг вверх на 1 см» и «сдвиг вниз на 1 см». Способов задания направления множество. В любом случае это определенные комбинации импульсов. С помощью этого таймера я определяю дребезг, длительность устойчивого импульса. С компьютера задается максимально допустимое время дребезга (10 микросекунд тут хватает), антидребезговое ожидание, минимальная/максимальная длительность импульса. Ну и есть режим отладки - датчик становится логическим анализатором. Это позволяет отлаживать работу линии и корректировать коэффициенты. Ну и опять же timeout, светодиоды.
  • Датчик аналоговых сигналов . Банальное 8-ми канальный АЦП. Здесь я использую таймер для выдерживания необходимых пауз.
Уважаемые хабрапользователи с других платформ могут мне подсказать код инициализации соответствующего таймера, а также правила доступа к нему - я это тут добавлю. Возможно, что для других платформ будет необходимо подобрать другие времена. Но в любом случае это должно быть нечто в пределах нескольких единиц микросекунд для самого таймера и нечто кратное 100 микросекунд для переменной-счетчика. Ибо, как оказалось, иногда одной миллисекунды не хватает.
Рассказать друзьям