Як зробити лічильник імпульсів з електронного годинника. Лічильники електричних імпульсів. Лічильники з паралельним перенесенням

Лічильник імпульсів— це послідовність цифровий пристрій, Що забезпечує зберігання слова інформації та виконання над ним мікрооперації рахунку, що полягає у зміні значення числа в лічильнику на 1. По суті лічильник є сукупністю з'єднаних певним чином тригерів. Основний параметр лічильника – модуль рахунку. Це максимальна кількістьодиничних сигналів, які можуть бути пораховані лічильником. Лічильники позначають через СТ (від англ. counter).

Лічильники імпульсів класифікують

● за модулем рахунку:
. двійково-десяткові;
. двійкові;
. з довільним постійним модулем рахунку;
. зі змінним модулем рахунку;
. за направленням рахунку:
. підсумовуючи;
. віднімають;
. реверсивні;
● за способом формування внутрішніх зв'язків:
. з послідовним перенесенням;
. з паралельним перенесенням;
. з комбінованим перенесенням;
. кільцеві.

Підсумовуючий лічильник імпульсів

Розглянемо підсумовуючий лічильник (рис. 3.67, а). Такий лічильник побудований на чотирьох JK-тригерах, які за наявності на обох входах логічного сигналу «1» перемикаються в момент появи на входах синхронізації негативних перепадів напруги.

Тимчасові діаграми, що ілюструють роботу лічильника, наведено на рис. 3.67, б. Через К сі позначено модуль рахунку (коефіцієнт рахунку імпульсів). Стан лівого тригера відповідає молодшому розряду двійкового числа, а правого старшому розряду. У вихідному стані на всіх тригерах встановлені логічні нулі. Кожен тригер змінює свій стан лише тоді, коли нього діє негативний перепад напруги.

Таким чином, цей лічильник реалізує підсумовування вхідних імпульсів. З часових діаграм видно, що частота кожного наступного імпульсу вдвічі менша, ніж попередня, тобто кожен тригер ділить частоту вхідного сигналу на два, що використовується у дільниках частоти.

Трирозрядний лічильник, що віднімає, з послідовним переносом

Розглянемо трирозрядний лічильник з послідовним перенесенням, схема і часові діаграми роботи якого наведені на рис. 3.68.
(xtypo_quote)У лічильнику використовуються три JK-тригери, кожен з яких працює в режимі Т-тригера (тригера з рахунковим входом).(/xtypo_quote)

На входи J і До кожного тригера подано логічні 1, тому приходу заднього фронту імпульсу, що подається на його вхід синхронізації, кожен тригер змінює попередній стан. Спочатку сигнали на виходах всіх тригерів рівні 1. Це відповідає зберіганню в лічильнику двійкового числа 111 або десяткового числа 7. Після закінчення першого імпульсу F перший тригер змінює стан: сигнал Q 1 стане рівним 0, a Q 1 - 1.

Інші тригери при цьому свій стан не змінюють. Після закінчення другого імпульсу синхронізації перший тригер знову змінює свій стан, переходячи в стан 1 (Q x = 0). Це забезпечує зміну стану другого тригера (другий тригер змінює стан з деякою затримкою по відношенню до закінчення другого імпульсу синхронізації, так як для його перекидання потрібен час, що відповідає часу спрацьовування його самого та першого тригера).

Після першого імпульсу F лічильник зберігає стан 11О. Подальша зміна стану лічильника відбувається аналогічно до викладеного вище. Після стану 000 лічильник знову перетворюється на стан 111.

Трирозрядний лічильник з послідовним переносом, що самозупиняється.

Розглянемо трирозрядний самозупиняється лічильник, що віднімає, з послідовним переносом (рис. 3.69).

Після переходу лічильника стан 000 на виходах всіх тригерів виникає сигнал логічного 0, який подається через логічний елемент АБО на входи J і До першого тригера, після чого цей тригер виходить з режиму Т-тригера і перестає реагувати на імпульси F.

Трирозрядний реверсивний лічильник із послідовним перенесенням

Розглянемо трирозрядний реверсивний лічильник із послідовним перенесенням (рис. 3.70).

У режимі віднімання вхідні сигнали повинні подаватися на вхід Т ст. На вхід Т з при цьому подається сигнал логічного 0. Нехай всі тригери знаходяться в стані 111. Коли перший сигнал надходить на вхід Т на вході Т першого тригера з'являється логічна 1, і він змінює свій стан. Після цього на його інверсному вході виникає сигнал логічної 1. При надходженні другого імпульсу на вхід Т на вході другого тригера з'явиться логічна 1, тому другий тригер змінить свій стан (перший тригер також змінить свій стан приходу другого імпульсу). Подальша зміна стану відбувається аналогічно. У режимі складання лічильник працює аналогічно 4-розрядному підсумовує лічильнику. При цьому сигнал подається на вхід Т с. На вхід Т подається логічний 0.
Як приклад розглянемо мікросхеми реверсивних лічильників (рис: 3.71) з паралельним перенесенням серії 155 (ТТЛ):
● ІЕ6 - двійково-десятковий реверсивний лічильник;
● ІЕ7 — двійковий реверсивний лічильник.

Напрямок рахунку визначається тим, який висновок (5 або 4) подаються імпульси. Входи 1, 9, 10, 15 - інформаційні, а вхід 11 використовується для попереднього запису. Ці 5 входів дозволяють здійснити попередній запис у лічильник (передустановку). Для цього потрібно подати відповідні дані на інформаційні входи, а потім подати імпульс запису низького рівня на вхід 11 і лічильник запам'ятає число. Вхід 14 - вхід установки Про при подачі високого рівня напруги. Для побудови лічильників більшої розрядності використовуються виходи прямого та зворотного перенесення(Висновки 12 і 13 відповідно). З виведення 12 сигнал повинен подаватися на вхід прямого рахунку наступного каскаду, а з 13 на вхід зворотного рахунку.

Лічильник на мікроконтроллері досить простий для повторення і зібраний на популярному МК 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. Виходи лічильника Q0, Q1, Q2, Q3 мають відповідно вагові коефіцієнти 1, 2, 4, 8. Поєднавши виходи Q 1 Q 2 з входами установки лічильника в нуль отримаємо лічильник з коефіцієнтом перерахунку шість (рис. 1.53,а). На малюнку 1.53 б показана схема підключення для отримання коефіцієнта перерахунку десять, а на малюнку 153 в - дванадцять. Однак у схемах, наведених на малюнках 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 Ст.

ЛІЧИЛЬНИК НА МІКРОКОНТРОЛЕРІ

У багатьох пристроях техніки та автоматики все ще встановлені механічні лічильники. Вони вважають кількість відвідувачів, продукцію на конвеєрі, витки дроту в намотувальних верстатах тощо. У разі виходу з ладу знайти такий механічний лічильник непросто, а відремонтувати неможливо через відсутність запчастин. Пропоную замінити механічний лічильник електронним з використанням мікроконтролера PIC16F628A.

Електронний лічильник виходить дуже складним, якщо будувати його на мікросхемах серій К176, К561. особливо якщо потрібний реверсивний рахунок. Але можна побудувати лічильник всього на одній мікросхемі - універсальному мікроконтролері PIC16F628A, що має у своєму складі різноманітні периферійні пристроїі здатне вирішувати широке колозадач.

Ось і недавно мене попросила людина зробити лічильник імпульсів на багато розрядів. Я відмовився від світлодіодних індикаторів, тому що вони займають багато місця та споживають чимало енергії. Тому реалізував схему LCD. Лічильник мікроконтролера може заміряти вхідні імпульси до 15 знаків розрядності. Два перші розряди відокремлені точкою. EEPROM не використовувалася, тому що не було потреби запам'ятовувати стан лічильника. Також є функція зворотного рахунку - реверсу. Принципова схема простого лічильника на мікроконтролері:

Лічильник зібраний на двох друкованих платахіз фольгованого склотекстоліту. Креслення наведено на малюнку.

На одній із плат встановлені індикатор LCD, на іншій - 4 кнопки, контролер та інші деталі лічильника, за винятком блоку живлення. Завантажити плати та схему лічильника в форматі Lay, а також прошивку мікроконтролера можна на форумі. Матеріал надав Samopalkin.

Часто при роботі мікроконтролерного пристрою є необхідність відраховувати «антропоморфний» час – скільки часткою секунди світитися світлодіоду, максимальний проміжок часу double-click тощо. , хвилини і навіть годинник (боюся сказати про добу ...).
У той же час у мікроконтролерах нерідко потрібно одночасно з цим мати справу з мікросекундами - періоди імпульсів, антибразгове очікування і т. п.
Є також пристрої, які працюють безперервно багато годин і навіть добу - авіаційна техніка, автомобільна, свердловинні пристрої (там йдеться іноді про безперервну роботу кілька днів). У цих випадках неприпустимо переповнення таймерів та 8-бітних змінних.
Хотілося б це все об'єднати в одне витончене та універсальне рішення– мати засіб вимірювання часу з точністю до мікросекунди, що не переповнюється кілька днів.
Чому б і ні? Помучився я деякий час і народив рішення для 8-бітних мікроконтролерів AVR. Для цього я задіяв 8-бітний таймер-лічильник та 4-байтну змінну. З PIC-ами та AT89 я зараз не працюю, а з іншими embedded-платформами не дружу. Втім, якщо читачі допоможуть, зроблю і для них.
Переваги - код дуже повторюваний (я вже п'яте пристрій з ним роблю); простота у роботі (не використовуються переривання для клієнтської частини роботи); клієнтська частина коду умовно-платформно-незалежна; у перериванні – одна операція підсумовування (але, щоправда, для 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 --включаємо обробку переривань

Як видно, прескалер тут вдвічі більше, тому PR2 вдвічі менше.
Дані налаштування будуть генерувати переривання з частотою 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) // немає пакетів? для поточного аналізу next_USB_timeout = dmsec + MaxSilence_PC_DEV; // timeout для загального обміну RECEIVE_BYTE (b) // заголовок пакета switch (b) ( case SetFullState: RECEIVE_DWORD (d); // читаємо слово is_initialized = 1; // ; break; ) // switch (pack) goto NewAnalyze; #undef RECEIVE_BYTE // скасовуємо #define #undef RECEIVE_WORD
Макрофункції RECEIVE_BYTE, RECEIVE_WORD, RECEIVE_DWORD реалізують процедури читання з урахуванням часу для даної фази обміну. У результаті, якщо чогось зависло на іншому боці, то мікроконтролер не впаде в «спячку». Зверніть увагу - 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_dms<<= 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 мікросекунд для змінної-лічильника. Бо, як виявилося, іноді однієї мілісекунди не вистачає. Операційні системи (ОС)