Как сделать часы на ATmega328P с кварцем 32 768 Гц?
Обновлено Редакция GAW
Содержание
У ATmega328P Timer2 умеет считать не от системного такта, а от собственного генератора на часовом кварце 32 768 Гц. Так получаются часы реального времени без внешней микросхемы, которые продолжают идти, пока процессор спит.
Ограничения из даташита
- Кварц подключается к TOSC1 и TOSC2 — это те же выводы PB6 и PB7, что XTAL1 и XTAL2. Поэтому системный такт должен идти от внутреннего RC-генератора (раздел 9.10 DS40002061B).
- Частота процессора — больше учетверённой частоты генератора, то есть больше 131 кГц.
- Запись в TCNT2, OCR2x и TCCR2x проходит через временные регистры; после включения AS2 их переписывают, а перед уходом в сон ждут, пока флаги занятости в ASSR сбросятся (раздел 18.9).
Расчёт секунды
Переполнение 8-битного счётчика наступает через 256 тактов таймера:
| Делитель N | CS22:0 | Период переполнения |
|---|---|---|
| 1 | 001 | 7,8 мс |
| 32 | 011 | 0,25 с |
| 128 | 101 | 1 с |
| 1024 | 111 | 8 с |
Наш расчёт по формуле; коды делителя — таблица 18-9.
Код
ISR(TIMER2_OVF_vect) { seconds++; }
void rtc_init(void) {
TIMSK2 = 0; /* 1: no Timer2 interrupts while switching */
ASSR = _BV(AS2); /* 2: clock Timer2 from TOSC */
TCNT2 = 0; /* 3: rewrite all registers after AS2 */
OCR2A = 0;
OCR2B = 0;
TCCR2A = 0; /* normal mode */
TCCR2B = _BV(CS22) | _BV(CS20); /* /128: overflow every 1 s */
while (ASSR & (_BV(TCN2UB) | _BV(OCR2AUB) | _BV(OCR2BUB) |
_BV(TCR2AUB) | _BV(TCR2BUB))) {} /* 4: wait for update */
TIFR2 = _BV(TOV2) | _BV(OCF2A) | _BV(OCF2B); /* 5: clear flags */
TIMSK2 = _BV(TOIE2);
sei();
}
void sleep_until_next_second(void) {
TCCR2B = _BV(CS22) | _BV(CS20); /* any write to a Timer2 register */
while (ASSR & _BV(TCR2BUB)) {} /* wait until it is latched */
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();
}
Порядок в rtc_init — безопасная процедура переключения из раздела 18.9 даташита: при смене AS2 регистры TCNT2, OCR2x и TCCR2x могут испортиться, поэтому их переписывают заново и ждут, пока флаги занятости в ASSR сбросятся. Генератору 32 кГц после подачи питания нужно время на запуск: даташит советует подождать не меньше одной секунды, прежде чем пользоваться Timer2, поэтому первую секунду отсчёта лучше не учитывать.
Перед каждым повторным уходом в Power-save в коде выше есть запись в регистр Timer2 и ожидание флага ASSR. Это тоже требование раздела 18.9: если заснуть в пределах того же такта TOSC1, в котором кристалл проснулся, прерывание сработает сразу ещё раз, и кристалл получит несколько пробуждений подряд.
В основном цикле кристалл можно усыплять в режим Power-save — Timer2 будит его раз в секунду, а типовой ток по таблице 29-8 составляет 0,9 мкА при 3 В. Режимы сна описаны на странице «Режимы сна AVR», остальные режимы таймеров — в обзоре таймеров AVR.
Почему кварц именно 32 768 Гц и какие ему нужны конденсаторы, рассказывает статья о часовом кварце. Если нужны часы с батарейкой и календарём без своей обвязки, проще поставить отдельную микросхему часов реального времени.
Похожие вопросы
Можно ли так сделать на Arduino Uno?
Нет. На Uno выводы XTAL1 и XTAL2 заняты кварцем 16 МГц, а асинхронный Timer2 по даташиту работает только при тактировании кристалла от внутреннего RC-генератора. Нужна своя плата с часовым кварцем на этих выводах или отдельная микросхема часов, например DS3231.
Насколько точны такие часы?
Точность определяет кварц, а не микроконтроллер: часовые кварцы задают отклонение в миллионных долях, и при 20 ppm уход составит около 1,7 секунды в сутки (наш расчёт: 86 400 с · 20 · 10⁻⁶). Подробнее — в статье о часовом кварце.
Сколько потребляет кристалл в таком режиме?
В режиме Power-save, когда работает только генератор 32 кГц и Timer2, даташит указывает типовые 0,9 мкА при 3 В. Реальный ток платы больше: добавляются стабилизатор, светодиод питания и утечки, поэтому мерить нужно всю схему.
Источники
- Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet, DS40002061B, 2020 — 9.10 — выводы TOSC1 и TOSC2 совпадают с XTAL1 и XTAL2, генератор таймера можно использовать, только если системный такт — калиброванный внутренний RC; 18.9 «Asynchronous Operation of Timer/Counter2» (с. 160) — частота процессора должна быть больше учетверённой частоты генератора, при переключении AS2 регистры TCNT2, OCR2x, TCCR2x могут испортиться — безопасная процедура: запретить прерывания Timer2, выбрать AS2, переписать регистры, дождаться флагов TCN2UB, OCR2xUB, TCR2xUB, сбросить флаги прерываний; перед повторным сном в Power-save записать регистр Timer2 и дождаться сброса флага занятости, иначе прерывание сработает несколько раз в одном такте TOSC1; генератору 32 кГц после включения питания может понадобиться до 1 с — пользоваться Timer2 не раньше чем через 1 с; 18.10 — бит AS2; табл. 18-9 — CS22:0 = 101 — делитель 128; табл. 29-8 — Power-save с генератором 32 кГц: 0,9 мкА при 3 В (типовое)
- AVR-LibC 2.3.2: <avr/iom328p.h>, <avr/sleep.h> — имена ASSR, AS2, TCN2UB, TCR2BUB, TIMER2_OVF_vect; set_sleep_mode(SLEEP_MODE_PWR_SAVE), sleep_mode()
Нашли ошибку?