AVR Урок 53. Watchdog Timer (WDT). Часть 2

В предыдущей части урока мы познакомились со сторожевым таймером (Watchdog Timer или WDT), узнали, как он устроен в микроконтроллере AVR, создали и настроили проект урока.

 

Включим ножки PD3:PD7 на выход, а ножку PD2 на вход. Ножки PD0 и PD1 не трогаем. Ножка PD2 нужна для отслеживания внешних прерываний

 

 

На ножках PD3:PD7 сначала установим низкий уровень, а с ножки PD2 подтянем резистор к питанию

 

 

Также включим на выход ножки PB0:PB4, выставив на них также низкий уровень

 

 

Настроим таймер 1 приблизительно с периодом в 0,5 секунды

 

 

Настроим внешние прерывания от ножки INT0 на срабатывания по спаду, так как при нажатии на кнопку у нас будет уровень ножки падать в ноль ибо она притянута вторым контактом к земле. Можно было сделать и по фронту, чтобы событие наступало при отжатии кнопки, только в таком случае событие наступит и в момент включения контроллера

 

 

Разрешим глобальные прерывания

 

 

Включим сторожевой таймер с интервалом 2 секунды

 

 

Вот так вот с помощью библиотечной функции очень быстро инициализируется Watchdog Timer.

Добавим глобальную переменную для сохранения счёта таймера

 

 

 

Также напишем макроподстановки для удобства управления светодиодами с ножек портов

 

 

Добавим обработчик прерываний от таймера, в котором будем попеременно при каждом вхождении зажигать очередной светодиод, а предыдущий тушить

 

 

Обработчик для внешнего прерывания пока не добавляем. Пока проверим, что таймер у нас работает правильно.

Соберём код с помощью вот этой кнопки либо с помощью функциональной клавиши F11

 

 

Если всё правильно соберётся, то в окне Output запомним местонахождения файла с прошивкой

 

 

Запустим программу avrdude33 (я пока не нашел способов её подключения к среде) и сначала убедимся в видимости нашего контроллера, нажав Чтение

 

 

Перейдём во вкладку настройки фьюзов и прочитаем их, также нажав кнопку Чтение. Значения должны быть именно такие. Если не такие, то добиваемся таких и прошиваем фьюзы

 

 

Возвращаемся на первую вкладку, выбираем файл с прошивкой и прошиваем её в контроллер

 

 

 

Светодиоды должны зажигаться по очереди, только как только дело дойдёт до того времени, как после включения сторожевого таймера программа проработает 2 секунды, контроллер перезагрузится и весь процесс начнётся сначала. Но, как ни странно, не совсем сначала, просто светодиод будет на время затухать, затем зажигаться тот же светодиод и программа будет продолжаться именно с этого же светодиода

 

 

Почему так происходит? Потому что мы явно не проинициализировали переменную счёта таймера, а проинициализировали её при объявлении глобально, скорей всего процедура перезагрузки затирает не всё. Поэтому произведём инициализацию данной переменной в функции main() явно

 

 

Соберём код, прошьём контроллер и убедимся, что теперь после перезагрузки по сторожевому таймеру процесс будет начинаться сначала

 

 

Отлично! Сторожевой таймер срабатывает правильно.

Следующая задача — расставить в процедуре обработки прерываний от таймера 1 сбросы сторожевого таймера раньше того момента, когда истечёт интервал времени настройки. Таймер 1 у нас работает с интервалом в полсекунды, значит достаточно будет воткнуть функции сброса сторожевого таймера в каждое третье вхождение в процедуру обработки прерывания. Нулевое не считаем, так как контроллер только что включился, считаем с первого. Для начала воткнём функцию только в третий кейс

 

 

Соберём код, прошьём контроллер. Теперь процедура перезагрузки контроллера начнётся только в момент начала зажигания 8-го светодиода

 

 

Поэтому вставим функцию перезагрузки сторожевого таймера ещё в седьмой кейс

 

 

Соберём код, прошьём контроллер.

Теперь светодиод до конца нормально добегает

 

 

Только вот после этого до третьего кейса дело не доходит, так как от седьмого до третьего интервал более 2 секунд.

Поэтому уберём все функции перезагрузки сторожевого таймера и расставим их немного по-другому в кейсы 2, 5 и 8

 

 

Соберём код, прошьём контроллер. Теперь светодиоды бегут и не затыкаются.

Если таймер будет работать нормально, то сторожевой таймер уже не сработает, а вот если «сломается» или зависнет, то контроллер перезагрузится, произойдёт повторная инициализация всей периферии и всё опять будет работать правильно.

Давайте наш таймер «сломаем». Это конечно всё сказано образно, мы не будем таймер высверливать из контроллера.

С помощью обработчика внешнего прерывания мы отключим наш таймер.

Добавим такой обработчик и отключим в нём прерывания от таймера 1

 

 

Соберём код, прошьём контроллер.

Теперь, если мы нажмём кратковременно на кнопку, то следующий светодиод у нас уже не загорится. Тот светодиод, который светится, будет светиться до тех пор, пока не истечёт интервал времени сторожевого таймера. Как только интервал истечёт, то контроллер перезагрузится и весь процесс возобновится

 

 

Таким образом, в данном уроке мы разобрались со сторожевым таймером (Watchdog timer), поняли, для чего он нужен и закрепили свои знания на практике.

Всем спасибо за внимание!

 

 

 

 

Исходный код

 

 

Приобрести плату Arduino Nano V3.0 оригинальный FT232RL можно здесь.

Приобрести программатор USBASP USBISP с адаптером можно здесь USBASP USBISP 3.3 с адаптером

 

 

Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)

AVR Watchdog Timer (WDT)

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

AVR Watchdog Timer (WDT)

1 комментарий к “AVR Урок 53. Watchdog Timer (WDT). Часть 2

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

*