Перейти к содержанию

Как сделать часы на 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 тактов таймера:

T=256⋅N32 768 ГцT = \frac{256 \cdot N}{32\,768\ \text{Гц}}
Делитель NCS22:0Период переполнения
10017,8 мс
320110,25 с
1281011 с
10241118 с

Наш расчёт по формуле; коды делителя — таблица 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 В. Реальный ток платы больше: добавляются стабилизатор, светодиод питания и утечки, поэтому мерить нужно всю схему.

Источники

  1. 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 В (типовое)
  2. 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()

Нашли ошибку?