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

Сторожевые таймеры STM32: IWDG и WWDG

Задайте нужное время до сброса или значения регистров — калькулятор подберёт предделитель и перезагрузку независимого сторожа IWDG или делитель, счётчик и окно оконного сторожа WWDG, покажет разброс таймаута по частоте LSI и выдаст код запуска.

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

Сторож
Что известно

По даташиту 30–60 кГц

мс

Результат

Таймаут
1 с
при LSI 40 кГц
IWDG_PR
2деление на 16
IWDG_RLR
2499 (0x9C3)шаг 400 мкс
Разброс по частоте LSI
666,67 мс … 1,3333 сLSI 30–60 кГц, DS5319 Rev 20, Table 25

Код на C с именами CMSIS

IWDG->KR = 0xCCCC;              /* start, LSI turns on */
IWDG->KR = 0x5555;              /* unlock PR and RLR */
IWDG->PR = 2;                   /* divider 16 */
IWDG->RLR = 2499;               /* reload value */
while (IWDG->SR != 0) {}        /* PR and RLR updated */
IWDG->KR = 0xAAAA;              /* reload the counter */

/* in the main loop */
IWDG->KR = 0xAAAA;

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

У STM32 два сторожевых таймера. IWDG (независимый) тактируется от собственного генератора LSI и работает, даже если основная частота остановилась, — он страхует от любого зависания. WWDG (оконный) тактируется от шины APB1, точен и проверяет окно: обновить его можно не раньше и не позже заданного момента.

Независимый сторож IWDG

Счётчик IWDG 12-битный: он считает вниз от значения перезагрузки RLR (0…4095) с частотой LSI, делённой на 4 · 2^PR. Время до сброса (RM0008, раздел 19; RM0090, раздел 21):

tIWDG=4⋅2PR⋅(RLR+1)fLSI.t_\text{IWDG} = \frac{4 \cdot 2^{PR} \cdot (RLR + 1)}{f_\text{LSI}}.

По таблицам руководств при LSI 40 кГц (STM32F1) таймаут — от 0,1 мс до 26,2 с, при 32 кГц (STM32F4) — от 0,125 мс до 32,8 с. Калькулятор выбирает наименьший предделитель, при котором нужное время ещё помещается в 4096 шагов, — так шаг таймаута получается самым мелким.

Запуск — запись 0xCCCC в IWDG_KR; при этом сам включается генератор LSI. Регистры PR и RLR защищены: перед записью нужен ключ 0x5555, а флаги PVU и RVU в IWDG_SR показывают, что новые значения ещё переносятся в домен сторожа. Обслуживание — запись 0xAAAA. Остановить запущенный IWDG нельзя, только сбросом.

Оконный сторож WWDG

Счётчик WWDG 7-битный и считает от PCLK1 / 4096 / 2^WDGTB. Сброс наступает, когда бит T6 становится нулём, то есть счётчик переходит от 0x40 к 0x3F:

tWWDG=tPCLK1⋅4096⋅2WDGTB⋅(T[5:0]+1).t_\text{WWDG} = t_\text{PCLK1} \cdot 4096 \cdot 2^{WDGTB} \cdot (T[5:0] + 1).

При PCLK1 = 36 МГц это от 113 мкс до 58,25 мс (таблица 98 RM0008), при 30 МГц — от 136,53 мкс до 69,91 мс (таблица 109 RM0090). Обновлять счётчик можно только когда он опустится до окна W или ниже; раньше — сброс. Бит EWI включает прерывание раннего предупреждения при счётчике 0x40, за один шаг до сброса.

Код

Код запуска IWDG повторяет порядок функции HAL_IWDG_Init из STM32CubeF4: запуск, ключ доступа, PR и RLR, ожидание флагов SR, перезагрузка. Для WWDG сначала записывают окно и делитель в CFR, затем включают сторож битом WDGA вместе со стартовым значением счётчика — с T6 = 1, иначе сброс произойдёт сразу.

Назначение каждого бита — на страницах регистров IWDG и WWDG STM32F1 и STM32F4.

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

Как посчитать таймаут IWDG?

t = 4 · 2^PR · (RLR + 1) / f_LSI. При LSI 40 кГц у STM32F1 и PR = 2 (деление на 16) один шаг длится 0,4 мс, и для 1 секунды нужно RLR = 2499. У STM32F4 с LSI 32 кГц та же секунда получается при PR = 1 и RLR = 3999.

Почему IWDG срабатывает раньше, чем рассчитано?

Генератор LSI очень неточный: у STM32F103 по даташиту DS5319 его частота от 30 до 60 кГц, у STM32F407 по DS8626 — от 17 до 47 кГц. При быстром LSI таймаут короче расчётного. Берите время с запасом по максимальной частоте — калькулятор показывает диапазон — или измерьте LSI таймером.

Как выбрать окно WWDG?

Окно W задаёт, раньше какого момента обновлять счётчик нельзя: пока счётчик больше W, запись в него вызывает сброс. Значение 0x7F снимает ограничение. Окно имеет смысл, когда цикл программы занимает известное время: так сторож ловит не только зависание, но и цикл, который пробежал слишком быстро.

Сколько длится таймаут WWDG при 24 МГц?

При PCLK1 = 24 МГц, WDGTB = 3 и T = 0x7F — 87,38 мс: 4096 · 8 · 64 / 24 МГц. В примере RM0008 и RM0090 для этих же значений напечатано 21,85 мс, но это расходится и с формулой, и с таблицами самих руководств; 21,85 мс получается при WDGTB = 1.

Источники

  1. STMicroelectronics. RM0008 Rev 21. Reference manual: STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx — гл. 19 — IWDG: ключи 0xCCCC, 0xAAAA, 0x5555, таблица 96 — таймауты при 40 кГц (эталон тестов); гл. 20 — WWDG: формула таймаута, таблица 98 при PCLK1 = 36 МГц (эталон тестов)
  2. STMicroelectronics. RM0090 Rev 22. Reference manual: STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439 — гл. 21 — IWDG, таблица 107 — таймауты при 32 кГц; гл. 22 — WWDG, таблица 109 при PCLK1 = 30 МГц — второй эталон тестов
  3. STMicroelectronics. DS5319 Rev 20. STM32F103x8, STM32F103xB datasheet — таблица 25 — частота LSI 30…40…60 кГц
  4. STMicroelectronics. DS8626 Rev 12. STM32F405xx, STM32F407xx datasheet — таблица 35 — частота LSI 17…32…47 кГц
  5. STMicroelectronics. STM32CubeF4 HAL: stm32f4xx_hal_iwdg.c — порядок запуска в HAL_IWDG_Init: 0xCCCC, 0x5555, PR и RLR, ожидание SR, 0xAAAA

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

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

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

<iframe src="https://gaw.ru/embed/stm32-watchdog/" title="Сторожевые таймеры STM32: IWDG и WWDG" 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/stm32-watchdog/">Сторожевые таймеры STM32: IWDG и WWDG</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>

Обновлено .

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