AVR134 годинник реального часу на tinyAVR та megaAVR, avr, programming
У датасітіAVR134 [1] описується реалізація годинника реального часу (Real Time Clock,RTC ) з наступними можливостями:
• RTC з дуже малим енергоспоживанням (4 мкА при напрузі живлення 3.3V) • Дуже недороге рішення • Підстроюваний прескалер з точністю • Підрахунок часу, дати, місяців, року з конфігурацією автоматичного високосного року >• Формат дати, сумісний з 2000 роком • Можна використовувати на всіх мікроконтролерах AVR, обладнаних модулем RTC • Разом з апноутом постачається код мовою C для ATMega128
У цьому апноуті показано, як зробити RTC на мікроконтролерах AVR®, які мають на борту модуль RTC. Реалізація потребує підключення лише одного зовнішнього компонента – часовий кварцовий резонатор на 32.768 кГц. Програма споживає дуже мало енергії, тому що мікроконтролер основну частину часу проводить у режимі зниженого енергоспоживання. У цьому режимі обчислювальне ядро AVR "спить", працює тільки таймер, що тактується від підключеного зовнішнього кварцу. При кожному переповненні таймера відбувається підрахунок часу, дати, місяця та року. Ця реалізація RTC написана для ATmega128, і може бути успішно портована на інші мікроконтролери AVR з модулем RTC. Переваги використання запропонованого варіанта RTC порівняно із застосуванням зовнішнього спеціального RTC-чіпа очевидні:
• Низька вартість • Мало зовнішніх компонентів, простота схеми (тільки 1 кварц) • Низьке енергоспоживання • Велика гнучкість
Прим. перекладача: насправді мікроконтролерів AVR, у яких є модуль RTC, не так багато, і багато з них дешевими назвати не можна. Нижче наведено їхній повний перелік на сьогоднішній день 150104.
8-бітні AVR з модулем RTC: AT90CAN32, AT90CAN64, AT90CAN128,AT90USB1286, AT90USB1287, AT90USB646, AT90USB647, ATmega128, ATmega128A, ATmega1280, ATmega1281, ATmega1284, ATmega16, ATmega16A, ATmega162, ATmega164, ATmega1 65, ATmega168, ATmega169, ATmega2560, ATmega2561, ATmega32, ATmega32A, ATmega324, ATmega324A, ATmega325, ATmega325A, ATmega3250, ATmega328, ATmega329, ATmega329A, ATmega3290, ATmega3290A, ATmega406, ATmega48, ATmega48A, ATmega64, ATmega64A, ATmega640, ATmega644, ATmega644A, ATmega645, ATmega645 A, ATmega6450, ATmega6450A, ATmega649, ATmega649A, ATmega6490, ATmega6490A, ATmega8, ATmega8A, ATmega8535, ATmega88, ATmega88A, ATtiny1634, ATtiny167, ATtiny828, ATtiny87.
8-бітні AVR XMEGA з модулем RTC: ATxmega128A1, ATxmega128A1U, ATxmega128A3, ATxmega128A3U, ATxmega128A4U, ATxmega128B1, ATxmega128B3, ATxmega128C3, ATxmega128D3, ATxm ega128D4, ATx mega16A4, ATxmega16A4U, ATxmega16C4, ATxmega16D4, ATxmega16E5, ATxmega192A3, ATxmega192A3U, ATxmega192C3, ATxmega192D3, ATxmega256A3, ATxmega256A3B, ATxmega256A3BU, ATxmega256A3U, ATxmega256C3, ATxmega256D3, ATxmega32A4, ATxmega32A4U, ATxmega32C3, ATxmega32C4, ATxmega32D3, ATxmega32D4, AT xmega32E5, ATxmega384C3, ATxmega64A1, ATxmega64A1U, ATxmega64A3, ATxmega64A3U, ATxmega64A4U, ATxmega64B1, ATxmega64B3, ATxmega64C3, ATxmega64D3, ATxmega64D4, ATxmega8E5.
32-бітні AVR з модулем RTC: AT32UC3A0128, AT32UC3A0256, AT32UC3A0512, AT32UC3A1128, AT32UC3A1256, AT32UC3A1512, AT32UC3A3128, AT32UC3A3256, AT32UC3A364 , AT32UC3A4128, AT32UC3A4256, AT32UC3A464, AT32UC3B0128, AT32UC3B0256, AT32UC3B0512, AT32UC3B064, AT32UC3B1128, AT32UC3B1256, AT32UC3B1512, AT32UC 3B164, AT32UC 3C0128C , AT32UC3C0256C, AT32UC3C0512C, AT32UC3C064C, AT32UC3C1128C, AT32UC3C1256C, AT32UC3C1512C, AT32UC3C164C, AT32UC3C2128C, AT32UC3C2256C, AT32UC 3C2512C, AT32UC 3C264C, AT32UC3L0128, AT32UC3L016,AT32UC3L0256, AT32UC3L032, AT32UC3L064, ATUC128D3, ATUC128D4, ATUC128L3U, ATUC128L4U, ATUC256L3U, ATUC256L4U, ATUC64 L4U.
[Трохи теорії: як це працює ]
Реалізація RTC використовує асинхронне функціонування модуля RTC. У цьому режимі Timer/Counter0 працює незалежно від частоти тактової ядра AVR.
На рис. 2-1 показано, як мікроконтролер AVR працює у звичайному режимі від основної тактової частоти 4 МГц. Коли потрібно працювати зі зниженим споживанням енергії, AVR перемикається в режим Power-down, у якому працює лише асинхронний таймер від частоти зовнішнього кристала 32768 кГц.
Програмно Real Time Clock (RTC) реалізовано з використанням 8-розрядного таймера/лічильника, що працює в режимі переривання по переповненню (Timer/Counter Overflow Interrupt). Програма керує перериванням переповнення для обчислення часу та змінних календаря. Переривання Timer Overflow використовується для коректного оновлення програмних змінних second (секунди), minute (хвилини), hour (годинник), date (дата), month (місяць) та year (рік).

Мал. 2-1. Підключення генератора до RTC.
Оскільки кількість часу, що проходить між переповненнями таймера лічильника те саме, кожна з цих змінних буде інкрементуватися на фіксоване число з кожним переповненням таймера. Для цього завдання використовується обробник переривання переповнення таймера (Interrupt Service Routine, ISR).
Для зниження енергоспоживання мікроконтролер AVR входить у режим збереження енергії (Power-save mode), у якому всі модулі мікроконтролера заборонені, крім RTC. Як показано в таблиці 2-1, ядро AVR зазвичай споживає у цьому режимі менше 4 мкА. Мікроконтролер прокинеться, коли відбудеться переривання попереповнення таймера (Timer Overflow Interrupt). Запуститься код обробки переривання в активному режимі ядра, який оновить змінні таймера.
Потім мікроконтролер AVR знову запустить режим збереження енергії (Power-save mode) і залишатиметься в ньому, поки не відбудеться наступне переривання Timer Overflow. На рис. 2-2 та 2-3 показано час, коли AVR працює в режимі збереження енергії (Power-save mode) у порівнянні з активним режимом (Active mode).
Щоб обчислити загальне споживання енергії, потрібно скласти споживання енергії Power-save mode із споживанням енергії в Active mode. Час, який потрібно оновлення змінних таймера в обробнику переривання, становить менше 100 циклів тактової частоти ядра, що у частоті 4 МГц становитиме 25 мкс. Споживання потужності цей короткий проміжок часу виходить несуттєвим. Набагато важливішим є час пробудження мікроконтролера (wake-up time). Воно може бути запрограмоване на 35 мс при використанні зовнішнього резонатора кварцового, або 1 мс для використання зовнішнього керамічного резонатора. Приклад схеми, які пробуджуються кожну секунду для оновлення змінних RTC, показують енергоспоживання двох типів джерел тактування:

Мал. 2-2. Діаграма струму для кварцового резонатора, час старту 35 мс (Startup Time).
Загальне споживання струму на секунду:
= (1 с * 4 мкA) + (35 мс * 6 мА) = 4 мкАс + 210 мкАс = 214 мкАс (мікроампер за секунду)
Це показує, що основна частина споживання струму посідає Active mode.

Мал. 2-3. Діаграма струму для керамічного резонатора, час старту 1 мс (Startup Time).
Загальне споживання струму на секунду:
= (1 с * 4 мкА) + (1 мс * 6 mA) = 4мкАс + 6 мкАс = 10 мкАс
Виходить, що зменшення тривалості запуску призведе до зменшення споживаного струму з 214 до 10 мкАс.
Таблиця 2-1. Споживання струму мікроконтролером AVR у кожному режимі.
Примітка (1): CK = 32768 кГц.
[Приклад конфігурації ]
Як показано на рис. 2-1, кварцовий резонатор має бути безпосередньо підключений до висновків мікроконтролера TOSC1 та TOSC2. Більш нові пристрої вимагають наявності на цих висновках додаткових зовнішніх конденсаторів (через відмінності в реалізації внутрішнього генератора), тому зверніться до даташиту на мікроконтролер, який використовується, щоб дізнатися подробиці щодо підключення зовнішнього резонатора. Генератор оптимізований на роботу з частою 32768 кГц від зовнішнього годинникового кварцу, або від зовнішнього тактового сигналу в інтервалі від 0 Гц до 256 кГц. У цьому прикладі реалізації 8 світлодіодів (LED) підключені до порту B мікроконтролера і використовуються для відображення стану RTC. LED на ніжці PB0 показуватиме зміну стану кожну секунду. Ще 6 LED (PB6..PB1) показують хвилини у двійковому вигляді, і останній LED, підключений до PB7, горить протягом години, і погашений протягом іншої години.
Необхідно враховувати деякі умови, коли таймер/лічильник тактується від асинхронного джерела по відношенню до системної тактової частоти. Кварцовий резонатор на 32768 кГц має час стабілізації до однієї секунди після включення живлення. Таким чином, мікроконтролер не повинен входити до режиму Power-save раніше, ніж після 1 секунди після включення живлення. Потрібно також подбати про перемикання режиму таймера на асинхронний режим. Докладніше про ці питання див. у датасіті на мікроконтролер. Дані регістру таймера передаються в тимчасовий регістр і замикаютьсятам після двох циклів зовнішніх тактів. Регістр статусу асинхронних операцій (Asynchronous Status Register, ASSR) містить прапори стану, які можна перевірити, щоб контролювати, коли записаний регістр оновився.
[Реалізація ]
Програмне забезпечення складається з переважно двох підпрограм. Процедура counter є обробником переривання переповнення таймера (Timer/Counter Overflow ISR), вона оновлює всі змінні таймера, коли відбувається переповнення лічильника таймера (ця подія відбувається кожну секунду). Друга процедура not_leap коригує дату з огляду на високосні роки. Основна програма налаштовує всі необхідні регістри введення/виводу, щоб дозволити роботу модуля RTC, і керувати послідовністю входу в режим економії енергії (Power-down).
Біт AS0 в регістрі ASSR (Asynchronous Status Register) встановлюється для конфігурування Timer/Counter0 для тактування зовнішнього джерела. Лише після цього таймер може працювати асинхронно. Таймер скидається, і йому встановлюється необхідний коефіцієнт розподілу прескалера (щоб частота тактування була 256 Гц, і таймер переповнювався після кожного 256-го імпульсу, т. е. кожну секунду). Для синхронізації із зовнішнім тактовим сигналом програма чекає, поки оновиться регістр ASSR. Потім встановлюється біт TOIE0 у регістрі TIMSK (Timer/Counter Interrupt Mask Register), щоб дозволити переривання Timer/Counter0 Overflow. Також встановлюється біт загального дозволу переривань (Global Interrupt Enable) у регістрі SREG (Status Register) – щоб дозволити роботу всіх переривань. Біти SM1 та SM0 у регістрі MCUCR (MCU Control Register) встановлюються для вибору режиму зниженого енергоспоживання (Power-save mode). Потім інструкція SLEEP переводить мікроконтролер у режим сну.Головний безкінечний цикл основної програми періодично виконує інструкцію SLEEP.
Підпрограма counter. Це обробник переривання переповнення таймера, він виконується щоразу, коли відбувається подія Timer Overflow. Це переривання пробуджує ядро мікроконтролера, щоб оновити змінні таймери. Процедура переривання обробника не приймає будь-які вхідні параметри, і не повертає з себе дані, як може робити звичайна функція. Натомість вона працює з глобальними змінними. Для цього декларується глобальна структура, що використовується для зберігання часу, з полями second, minute, hour, date, month та year. Оскільки відомий час, який минув між перериваннями таймера (1 секунда), поле second буде кожного разу інкрементуватися на 1. Як тільки поле second досягне 60, то поле minute буде інкрементовано на 1, і поле second встановиться в 0.

Мал. 5-1. Алгоритм роботи підпрограми обробника переривання Counter.
Підпрограма not_leap. Ця підпрограма перевіряє, чи є зараз високосний рік. Вона повертає true, якщо рік не високосний, і false, якщо високосний. Вважається, що рік високосний, якщо задовольняються обидві умови:
1. Число року ділиться націло на 4. 2. Якщо рік ділиться націло на 100, він також ділиться націло на 400.

Мал. 5-2. Алгоритм роботи функції not_leap.
Ініціалізація. Функція init() робить усі необхідні дії з налаштування RTC, портів вводу/виводу, тактування таймера.
Основна програма (функція main). Ця функція запускається відразу після включення живлення (скидання) і в ній знаходиться нескінченний цикл системи. Перед запуском нескінченного циклу відбувається ініціалізація викликом підпрограми init(), а вВ основному циклі відбувається постійний вхід в режим сну, і при виході зі сну відбувається очікування оновлення регістрів Timer/Counter0.
[Точність ]
RTC, реалізовані на AVR, працюють настільки точно, наскільки точна частота, що генерується кварцовим генератором. Асинхронне функціонування дозволяє таймеру працювати без будь-яких затримок, пов'язаних з роботою ядра - воно може виконувати (або не виконувати) будь-які найскладніші обчислення, на роботу асинхронного таймера це ніяк не вплине. Однак насправді є незначна невідповідність часу, що зчитується основною програмою, через те, що змінні таймери не можуть бути оновлені паралельно. Час, за який оновлення завершується, змінюється дуже мало залежно від стану таймера/лічильника. Найбільша відмінність виникає, коли переповнюються всі змінні таймери. У цей момент поле second = 59, minute = 59, hour = 23 і так далі. Це займе 94 цикли часу ядра для завершення оновлення. На тактовій частоті ядра 4 МГц помилкове розбіжність між RTC і часовим кварцом не перевищить 23.5 мкс (обчислено як 94/(4*10^6)). Зазвичай помилка становитиме 6 мкс, тому що на оновлення поля second потрібно 24 цикли. Ця помилка не накопичується, тому що таймер завжди синхронний із частотою годинникового кварцу, і не зупиняє рахунок.
[Витрати ресурсів ]
Таблиця 7-1. Витрати тактів процесорного часу та витрати пам'яті AVR.