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), поняли, для чего он нужен и закрепили свои знания на практике.

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

 

 

Предыдущая часть Программирование МК AVR Следующий урок

 

 

Исходный код

 

 

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

Программатор (продавец надёжный) USBASP USBISP 2.0

 

 

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

 

AVR Watchdog Timer (WDT)

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

    Класс! Сперва не понял, потом дошло. Спасибо!

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

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

*