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

Сторожевой таймер AVR: время срабатывания и настройка

Выберите микроконтроллер, режим и предделитель — калькулятор покажет время срабатывания сторожевого таймера по номинальной или измеренной частоте генератора, типичное значение из даташита, константу WDTO для wdt_enable() и код настройки с обязательной последовательностью WDCE.

Исходные данные

Режим
кГц

пусто — номинальные 128 кГц

с

подберёт WDP, который не сработает раньше

Результат

Время до срабатывания
1,024 с
131072 тактов генератора 128 кГц
Типичное по даташиту
1 спри VCC = 5 В
Константа avr-libc
WDTO_1Sбиты (1 << WDP2) | (1 << WDP1) в WDTCSR
При срабатывании
сброс микроконтроллера

Генератор сторожевого таймера неточен: частота зависит от питания и температуры. Сбрасывайте сторож с большим запасом по времени.

Код на C (avr-libc)

#include <avr/wdt.h>

wdt_enable(WDTO_1S);   /* 131072 oscillator cycles */
for (;;) {
    /* ... */
    wdt_reset();               /* before the time-out */
}

Расчёт выполнен по формулам и данным из источников, приведённых на этой странице, и не заменяет проверку: параметры компонентов у разных производителей и даже партий различаются. Перед применением сверяйте результат с документацией на конкретные детали.

Сторожевой таймер (WDT) — отдельный счётчик со своим генератором, который сбрасывает микроконтроллер или вызывает прерывание, если программа вовремя не выполнила команду WDR (wdt_reset()). У AVR он работает даже при остановленном основном генераторе и годится как для защиты от зависаний, так и для периодического пробуждения из сна.

Время срабатывания

У ATmega328P, ATmega2560, ATmega32U4 и ATtiny85 сторож считает такты собственного генератора 128 кГц, у старого ATmega8 — генератора 1 МГц. Предделитель WDP выбирает число тактов до срабатывания:

WDPТактов (128 кГц)Типично при 5 ВКонстанта avr-libc
00002K16 мсWDTO_15MS
00014K32 мсWDTO_30MS
00108K64 мсWDTO_60MS
001116K0,125 сWDTO_120MS
010032K0,25 сWDTO_250MS
010164K0,5 сWDTO_500MS
0110128K1,0 сWDTO_1S
0111256K2,0 сWDTO_2S
1000512K4,0 сWDTO_4S
10011024K8,0 сWDTO_8S

Таблица одинакова у всех четырёх микроконтроллеров (ATmega328P — таблица 11-2, ATmega2560 — 12-2, ATmega32U4 — 8-5, ATtiny85 — 8-3). Даташиты округляют времена: 1024K тактов при ровно 128 кГц — это 8,19 с. У ATmega8 тактов вдвое и больше, а генератор быстрее: от 16K тактов (16,3 мс при 5 В) до 2048K (2,1 с), и при 3 В времена примерно на 5 % длиннее (таблица 17).

Генератор сторожа экономичный, но неточный: ATmega328P нормирует его частоту 128 кГц только при 3 В и 25 °C и прямо пишет, что он не рассчитан на высокую точность (раздел 9.7). Поэтому сторож сбрасывают с большим запасом, а если время важно — измеряют частоту генератора на своём экземпляре и вводят её в калькулятор.

Режимы и настройка

WDTONWDEWDIEРежим
не запрограммирован00выключен
не запрограммирован01прерывание
не запрограммирован10сброс
не запрограммирован11прерывание, затем сброс
запрограммированxxсброс, отключить нельзя

Таблица — по ATmega328P (таблица 11-1). В режиме «прерывание, затем сброс» первое срабатывание вызывает прерывание и аппаратно сбрасывает WDIE; если до следующего срабатывания программа не установит WDIE снова, произойдёт сброс. Так перед перезагрузкой можно сохранить важные данные. Фьюз WDTON включает сторож навсегда в режиме сброса — его состояние показывает калькулятор фьюзов AVR.

Изменить предделитель или выключить сторож можно только последовательностью из двух записей: сначала одновременно WDCE = 1 и WDE = 1, затем в течение четырёх тактов — новое значение регистра с WDCE = 0 (ATmega328P, раздел 11.8). Прерывания на это время запрещают. Перед выключением сторожа нужно сбросить флаг WDRF в MCUSR: пока он установлен, WDE нельзя сбросить. Функция wdt_enable() из avr-libc выполняет эту последовательность сама.

Сторожевые таймеры STM32 устроены иначе — независимый IWDG и оконный WWDG; их считает калькулятор сторожевых таймеров STM32.

Частые вопросы

Почему после срабатывания сторожа Arduino бесконечно перезагружается?

У ATmega328P и других AVR с прерыванием от сторожа таймер после сброса остаётся включённым с самым коротким временем, около 16 мс (avr-libc, avr/wdt.h). Если программа или загрузчик не успевают его выключить, микроконтроллер сбрасывается снова и снова. Даташит требует в начале программы сбрасывать флаг WDRF в MCUSR и бит WDE — даже если сторож не используется.

Какое наибольшее время сторожевого таймера ATmega328P?

1024K тактов генератора 128 кГц — около 8 с (WDP3:0 = 1001, константа WDTO_8S). У ATmega8 наибольшее время — 2048K тактов генератора 1 МГц, около 2,1 с при 5 В.

Можно ли разбудить AVR сторожевым таймером?

Да, в режиме прерывания (WDIE = 1, WDE = 0) сторож вызывает прерывание WDT_vect, которое выводит микроконтроллер из сна, в том числе из самого экономного режима Power-down (ATmega328P, раздел 10.5). Так делают периодическое пробуждение батарейных устройств с потреблением в микроамперы. У ATmega8 прерывания от сторожа нет — только сброс.

Источники

  1. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — 9.7 — генератор 128 кГц номинален при 3 В и 25 °C и не рассчитан на точность; 11.8 — режимы, WDTON, последовательность WDCE, сброс WDRF при инициализации; 10.5 — прерывание сторожа будит из Power-down; таблица 11-1 — режимы; таблица 11-2 — 2K…1024K тактов, 16 мс…8 с при 5 В (эталон тестов)
  2. Microchip (Atmel). ATmega640/1280/1281/2560/2561 datasheet (2549Q) — таблица 12-2 — те же 2K…1024K тактов и времена (второй источник тестов)
  3. Microchip (Atmel). ATmega16U4/32U4 datasheet (Atmel-7766J) и ATtiny25/45/85 datasheet (2586Q) — ATmega32U4: таблица 8-5; ATtiny85: таблица 8-3 и регистр WDTCR — в строке 32K напечатано 32764 вместо 32768
  4. Microchip (Atmel). ATmega8(L) datasheet (2486AA) — генератор 1 МГц, таблица 17 — 16K…2048K тактов, 16,3 мс…2,1 с при 5 В и 17,1 мс…2,2 с при 3 В; только сброс
  5. avr-libc. avr/wdt.h (репозиторий avrdudes/avr-libc) — wdt_enable(), wdt_reset(), константы WDTO_15MS…WDTO_8S (4S и 8S — при наличии WDP3); сторож остаётся включённым после сброса, кроме сброса по питанию

Где пригодится

Встроить калькулятор на свой сайт

Скопируйте код и вставьте его в HTML страницы, статьи или вики. Виджет бесплатный, без рекламы, счётчиков и cookie. Условие одно — ссылка на GAW под рамкой остаётся на месте. Подробнее о виджетах

<iframe src="https://gaw.ru/embed/avr-watchdog/" title="Сторожевой таймер AVR: время срабатывания и настройка" width="100%" height="640" style="border:1px solid #e3e5e9;border-radius:8px" loading="lazy" allow="clipboard-write"></iframe>
<p style="margin:6px 0 0;font-size:14px">Калькулятор: <a href="https://gaw.ru/tools/avr-watchdog/">Сторожевой таймер AVR: время срабатывания и настройка</a> — GAW.ru</p>
Автоподстройка высоты рамки

Если сайт разрешает скрипты, добавьте этот код один раз в любом месте страницы: рамка будет менять высоту вместе с результатом расчёта.

<script>window.addEventListener("message",function(e){if(e.origin!=="https://gaw.ru"||!e.data||e.data.type!=="gaw:embed-height")return;var f=document.querySelectorAll('iframe[src^="https://gaw.ru/embed/"]');for(var i=0;i<f.length;i++)if(f[i].contentWindow===e.source)f[i].style.height=e.data.height+"px"})</script>

Обновлено .

Нашли ошибку в расчёте?