Здравствуйте, уважаемые читатели! В этой статье поговорим о таком понятии, как Сторожевой таймер или Watchdog. Что это такое и как с ним работать.
Данный таймер есть у всех AVR микроконтроллеров, даже у малыша ATtiny10. У которого изменению режима работы Сторожевого таймера посвящен один из всего трех его фьюзов WDTON. Как работать с фьюзами на Тини10 я рассказывал в отдельной статье "Изменение фьюзов на ATtiny10".
Что такое Сторожевой таймер (Watchdog)?
Основное назначение Сторожевой таймера – предотвратить зависание микроконтроллера в процессе выполнения программы. Т.е. мы запускаем данный таймер и если в течение установленного нами интервала времени счетчик Watchdog не будет перезапущен, то уже будет перезагружен сам микроконтроллер. Но на самом деле возможности Сторожевой таймера больше, чем просто перезагружать микроконтроллер. О чем мы и поговорим далее.
Сторожевой таймер обладает собственным тактовым генератором, отдельным от основного тактового генератора микроконтроллера. Обычно частотой 128 кГц.
Здесь и далее я буду рассматривать даташит на ATtiny13. Но информация из данного ролика актуальна, с небольшими поправками о которых я расскажу далее, и для других AVR микроконтроллеров.
Управляет всеми режимами работы Сторожевого таймера всего один регистр Watchdog Timer Control Register (WDTCR) состоящий из одного байта с набором конфигурационных бит.
Биты WDE и WDTIE определяют режим работы Watchdog. Вернее к какому результату приведет срабатывание Сторожевого таймера. В размещенной ниже таблице, в которой указано, как данные биты настраиваются:
Если WDE и WDTIE по нулям – у нас Сторожевой таймер остановлен.
Присваивая единицу WDTIE мы определяем, что результатом работы сторожевого таймера будет срабатывание прерывания.
А WDE равный единице, будет означать, что результатом работы сторожевого таймера будет Reset, т.е. перезагрузка микроконтроллера.
Если же обоим битам WDE и WDTIE присвоена единица, то у нас сработает и прерывание и Reset. Т.е. сначала сработает прерывание, а затем микроконтроллер перезапустится. Т.е. в этом случаем мы можем сохранить какую-то важную информацию, полученную в ходе работы скетча или код ошибки, например в EEPROM памяти, а затем перезагрузить микроконтроллер.
Это всё при условии, что у нас фьюз бит WDTON равен единице. Т.е. вспоминаем особенность фьюзов, о которой я рассказывал в статье "Что такое фьюзы? Как работать с фьюзами на микроконтроллерах AVR", единица означает, что данный фьюз, не установлен. Если же установить фьюз WDTON, то неважно, как у нас заданы биты WDE и WDTIE, срабатывание Сторожевого таймера будет приводить только к перезагрузке микроконтроллера.
Бит WDTIF работает когда Watchdog настроен на Прерывание. И микроконтроллер сам с ним работает и очищает, когда прерывание выполнено.
Бит WDCE временно разрешает изменение параметров работы сторожевого таймера. Т.е. прежде, чем изменить режим работы Watchdog мы должны записать в этот бит единицу, а затем изменить нужный нам параметр. Через 4 такта данный параметр будет аппаратно сброшен на 0.
И биты WDP0, WDP1, WDP2 и WDP3 устанавливают количество тактов, прежде чем наступит срабатывание Сторожевого таймера. Ниже расположена таблица, где указано, какие значения мы можем установить данным битам и какое получить количество циклом до срабатывания Watchdog и сколько это примерно в миллисекундах и секундах.
Значение можно задать от 16 мс до 8 секунд. И следует учитывать, что это время указано при напряжении питания в 5В. Т.к. частота внутреннего кварцевого генератора зависит от напряжения и снижается при его понижении.
Очень важной особенностью является то, что имена конфигурационных бит, имя регистра таймера Watchdog и возможные варианты его работы отличаются у разных микроконтроллеров!
В этой статье, я привожу пример для ATtiny13.
А вот для ATtiny25/45/85 название регистра WDTCR совпадает с ATtiny13
А вот конфигурационного бита, отвечающего за включение прерывания, по срабатыванию счетчика Watchdog отличается. Он здесь WDIE, в отличие от WDTIE на ATtiny13.
А вот у ATmega328 отличается от ATtiny13 и название бита, связанного с прерыванием по Watchdog и название регистра. Тут он WDTCSR, т.е. с буквой "S" перед "R".
У ATtiny2313, о котором я рассказывал в отдельной статье "Микроконтроллер ATtiny2313. Обзор, программирование, сравнение с другими микроконтроллерами", имена и бита и регистра точно такие же, как у ATmega328.
А вот, например, у ATmega8 регистр именуется так же, как и у ATtiny13 WDTCR, но нет возможности инициировать Прерывание по срабатыванию Сторожевого таймера. Только перезагрузку микроконтроллера (Reset).
И максимальное время которое мы можем установить до срабатывания сторожевого таймера составляет чуть больше 2х секунд.
Так что учитывайте такие особенности при работе с разными микроконтроллерами!
Watchdog и перезагрузка микроконтроллера (Reset)
Для того, чтобы настроить срабатывание Watchdog на перезагрузку микроконтроллера, нам нужно вначале разрешить изменение таймера Watchdog, а далее сконфигурировать его на перезагрузку микроконтроллера и указать время работы (вернее число тактов) таймера Watchdog, после которого он перезапустит микроконтроллер:
WDTCR|=(1<<WDCE) | (1<<WDE); //Разрешаем изменение Watchdog
WDTCR = (1<<WDE) | (1<<WDP3); //Конфигурируем Watchdog на Reset через 4 с
Записывая единицу в конфигурационный бит WDE, мы устанавливаем режим перезагрузки микроконтроллера по срабатыванию Сторожевого таймера. Согласно размещенной выше таблице 8-1 даташита на ATtiny13.
А записывая единицу в конфигурационный бит WDP3, мы устанавливаем число тактов до срабатывания Watchdog в 512K (524288) циклов, что соответствует примерно 4-м секундам при напряжении питания в 5 В. Всё согласно размещенной выше таблице 8-2 даташита на ATtiny13.
В конце статьи есть ссылка на скетч с демонстрационным примером, а так же видео с подробным разбором всех скетчей и результатом их работы.
Watchdog и прерывание (Interrupt)
Чтобы настроить срабатывание Watchdog на вызов, нам, как и в прошлом случае, нужно вначале разрешить изменение таймера Watchdog, а далее записать единицу в конфигурационный бит WDTIE:
WDTCR|=(1<<WDCE) | (1<<WDE); //Разрешаем изменение Watchdog
WDTCR = (1<<WDTIE) | (1<<WDP3); //Конфигурируем Watchdog на Прерывание через 4 с
После срабатывание Watchdog будет вызвано прерывание и исполнен код, записанный в соответствующий блок:
ISR(WDT_vect){
//код
}
Watchdog и прерывание (Interrupt)+перезагрузка (Reset)
В данном случаем, если мы зададим единицу и биту WDE и биту WDTIE вначале сработает прерывание, а затем микроконтроллер будет перезагружен:
WDTCR|=(1<<WDCE) | (1<<WDE); //Разрешаем изменение Watchdog
WDTCR = (1<<WDE) | (1<<WDTIE) | (1<<WDP3); //Конфигурируем Watchdog на Прерывание через 4 с и Reset
Т.е. здесь у нас может быть заложено включение подачи сигнала, звукового или светового, что у нас произошел сбой в работе устройства. Или можем записать код ошибки или значения переменных, полученных при работе скетче в энергонезависимую память. А после, микроконтроллер перезагрузится.
Вся информация из статью наглядно показана в размещенном ниже видео:
Ссылки на скетчи:
Watchdog Reset - https://disk.yandex.ru/d/uJYPK0dVxb1IIQ
Watchdog Прерывание (Си) - https://disk.yandex.ru/d/56mIrfFhk_Ti4A
Watchdog Прерывание + Reset (Си) - https://disk.yandex.ru/d/BkY4ZZHMIHaMnA
_________________________________________________________
Спасибо, что дочитали до конца! Если статья понравилась, нажмите, пожалуйста, соответствующую кнопку. Если интересна тематика электроники и различных электронных самоделок, подписывайтесь на канал. До встречи в новых статьях!
Другие публикации по теме:
- Изменение фьюзов на ATtiny10
- Что такое фьюзы? Как работать с фьюзами на микроконтроллерах AVR
- ATtiny13 и ATtiny85. Обзор и программирование с помощью Arduino.
- Создаем удобный модуль для программирования микроконтроллеров ATtiny