STM32 и watchdog. STM32CubeMx. Настройка модуля WWDG.

Сторожевой таймер

Одна из предыдущих статей была посвящена знакомству с одним из сторожевых таймеров микроконтроллеров STM32 – IWDG, и вот пришло время обсудить и второй тип watchdog таймера, а именно WWDG! Задачи, которые призван решать WWDG, в целом, аналогичны тем задачам, которые решает сторожевой таймер IWDG, поэтому давайте сразу же сосредоточимся на отличиях. А отличия есть, и не одно!

  • Во-первых, в отличие от IWDG, который тактируется от низкочастотного генератора, WWDG тактируется, как и большинство остальных модулей микроконтроллера, от высокочастотного генератора. Частота тактирования таймера WWDG получается делением частоты PCLK1 (частота шины APB1) на постоянный делитель 4096. Кроме того, в настройках таймера мы можем добавить еще и дополнительный предделитель. Его возможные значения равны 1, 2, 4 и 8.
  • Во-вторых, отличие есть и в самом принципе работы. Если IWDG перезапускал контроллер в том случае, если он досчитает до 0, то WWDG работает иначе.

Собственно, на втором пункте остановимся поподробнее.

Значение периода WWDG мы можем установить равным величине, которая лежит в пределах от 64 до 127. Таким образом, таймер начинает считать вниз от того значения, которое мы в него записали, до 63. А, досчитав до 63, перезапускает контроллер.

Еще одним существенным отличием является то, что при работе с IWDG мы могли “перезагрузить” счетный регистр таймера в любой момент времени. WWDG же мы можем “обновить” только в определенный временной промежуток, который задается параметром Window value. Этот параметр мы также можем установить равным любому числу от 64 до 127.

Сейчас рассмотрим небольшой пример для лучшего понимания процесса.

Пусть значение периода таймера равно 100, а значение окна – 80. Включаем сторожевой таймер и он начинает считать от 100 до 63. Обновить значение WWDG мы сможем только после того, как таймер досчитает до 80. Если мы сделаем это раньше установленного срока, то произойдет перезапуск контроллера. Также контроллер будет перезапущен в том случае, если таймер досчитает до 63. При таких настройках параметров таймера мы можем обновить его счетный регистр в те моменты, когда его значение лежит в интервале от 63 до 80.

Вот как все это выглядит:

Принцип работы сторожевого таймера

И еще одним отличием WWDG от IWDG является то, что у WWDG есть свое собственное прерывание. Оно вызывается непосредственно перед перезапуском контроллера, когда таймер уже досчитал до 63. Нужно это для того, чтобы сохранить какие-нибудь важные данные, которые могут быть утеряны при перезапуске.

Давайте теперь перейдем в STM32CubeMx и создадим небольшой пример для демонстрации того, что мы сегодня обсудили. Активируем WWDG и внешний кварцевый резонатор:

Настройка watchdog таймера в STM32.

Настройки тактирования в STM32CubeMx мы уже обсуждали, поэтому не буду приводить скриншот – у меня на APB1 приходит 24 МГц. Поставим значение периода таймера 120, предделитель – 1, а значение окна – 80. И заодно активируем прерывание во вкладке NVIC Settings:

STM32 watchdog период.

Тогда таймер перезапустится по истечению интервала:

T = \frac{1000}{24000000} \medspace \cdot \medspace 4096 \cdot \medspace 1 \cdot (120 \medspace – \medspace 63) = 9.73\medspace мс

То есть если мы запустим таймер, но не будем обновлять значение счетчика, то контроллер перезапустится через 9.73 мс. Давайте также рассчитаем, по истечению какого интервала времени мы сможем обновлять значение счетного регистра:

T = \frac{1000}{24000000} \medspace \cdot \medspace 4096 \cdot \medspace 1 \cdot (120 \medspace – \medspace 80) = 6.82\medspace мс
  • \frac{1000}{24000000} – находим период (в мс), соответствующий частоте 24 МГц.
  • Поскольку частота WWDG дополнительно делится на 4096, то длительность тика умножаем на 4096.
  • 1 – это наш дополнительный предделитель – он равен единице.
  • Выражение \frac{1000}{24000000} \medspace \cdot \medspace 4096 \cdot \medspace 1 – это длительность одного “тика” таймера. Теперь остается только умножить ее на нужное количество тиков.

Таким образом, мы должны действовать так:

  • Запускаем WWDG
  • Проверяем, если с момента запуска/обновления регистра прошло 6.82 мс – обновляем значение счетчика

Давайте теперь посмотрим, как это реализовано программно. Инициализация:

/* WWDG init function */
void MX_WWDG_Init(void)
{
	hwwdg.Instance = WWDG;
	hwwdg.Init.Prescaler = WWDG_PRESCALER_1;
	hwwdg.Init.Window = 80;
	hwwdg.Init.Counter = 120;
	HAL_WWDG_Init(&hwwdg);
}

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

HAL_WWDG_Start_IT(&hwwdg);

Обновление значения счетчика производится так:

HAL_WWDG_Refresh(&hwwdg, 120);

Ну и сам обработчик прерывания:

/**
* @brief This function handles Window Watchdog interrupt.
*/
void WWDG_IRQHandler(void)
{
	/* USER CODE BEGIN WWDG_IRQn 0 */

	/* USER CODE END WWDG_IRQn 0 */
	HAL_WWDG_IRQHandler(&hwwdg);
	/* USER CODE BEGIN WWDG_IRQn 1 */

	/* USER CODE END WWDG_IRQn 1 */
}

В общем-то все реализовано довольно просто , гораздо сложнее оказался сам принцип работы сторожевого таймера WWDG. Думаю на этом можно и закончить сегодняшнюю статью. Оставайтесь с нами и следите за обновлениями!

Поделиться!

Подписаться
Уведомление о
guest
1 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
RusikOk
RusikOk
3 лет назад

зачем же все эти сложности нужны? каков реальный сценарий использования этих наворотов с окнами и счетчиком до 63 вместо 0?

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Август 2020
Пн Вт Ср Чт Пт Сб Вс
 12
3456789
10111213141516
17181920212223
24252627282930
31  

© 2013-2020 MicroTechnics.ru