Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Листинг 14,6
cli wdr
ldi trap, (1«WDE) I (1«WDP2) | (1«WDP1) I (1«WDP0) out WDTCR,tmp sei

Для семейства Mega процедура несколько сложнее: сначала нужно установить биты WDCE и WDE одновременно, потом повторно разрешить работу установкой WDE и одновременно установить коэффициент деления, но при сброшенном WDCE: (ЛИСТИНГ 14.7).
Листинг 14.7

cli wdr
ldi tmp, (1«WDCE) | (1«WDE) out WDTCR,tmp
ldi tmp, (1«WDE) I (1«WDP2) | (1«WDP1) I (1«WDP0) out WDTCR,tmp sei
Процедура выключения одинакова для всех моделей и аналогична включению в предыдущем случае (листинг 14.8).

cli wdr
ldi tmp, (1«WDCE) | (1«WDE) out WDTCR,tmp ldi tmp, (0«WDE) out WDTCR,tmp sei
Отметим, что инструкция рекомендует немного другую последовательность операций, например для выключения (листинг 14.9).

Листинг 14.9
wdr ;Reset WDT
in temp, WDTCR
ori temp, (1«WDCE) I (1«WDE)
out WDTCR, temp
ldi temp, (0«WDE) ; выключить WDT out WDTCR, temp

Кажется, что раз в регистре WDTCR больше нет никаких разрядов, кроме WDCE, WDE и WDPX (старшие три бита WDTCR не задействованы), применение инструкции ori, чтобы не трогать биты, кроме необходимых, довольно бессмысленно. На самом деле это не совсем так: нашей операцией мы обнуляем коэффициент деления, и если WDT был близок к срабатыванию, то теоретически не исключена ситуация, что он успеет сбросить систему до окончательного выключения. На практике это, однако, чистая перестраховка.
При включенном постоянно таймере через fuse-бит WDTON (В инструкциях это именуется режимом 2) все операции аналогичны, только нулевое состояние бита WDE не выключает таймер — фактически здесь доступно только изменение коэффициента деления, хотя внешне все выглядит так же, как при обычном включении.

Интересный случай представляет ATtiny2313 (именно он, а не его "классический" аналог), где WDT может работать в двух режимах: установкой бита WDIE в регистре управления (здесь он называется WDTCSR) МОЖНО вместо сброса по истечении заданного периода получить специальное прерывание WDT Overflow. Эта возможность несколько усложняет процедуру инициализации и выключения WDT, т. к. приходится заботиться о состоянии флага прерывания WDRF В регистре MCUSR, сбрасывая его перед каждой операцией. Это также рекомендуется осуществлять при начальном включении (как и для регистров прерываний TIFR И GT.FR):

in temp, MCUSR
andi temp, (Oxff & (0«WDRF) )
out MCUSR,temp

После того как мы разобрались с включением, WDT начинает постоянно "молотить" (в том числе и в режиме энергосбережения), и чтобы избежать сброса МК в нормальном режиме работы программы, таймер следует периодически сбрасывать командой wdr— раньше, чем истечет заданный период. Обычно это делается по какому-либо прерыванию.
Например, в описанной ранее программе с часами DS1307 это можно делать по каждому прерыванию INTO:
EXT_INT0:
wdr ;сброс сторожевого таймера

Предполагается, что мы установили WDT на период 2 с. Так как прерывание должно возникать каждую секунду, то мы сбрасываем таймер заведомо раньше, чем он сработает, и тогда он начнет отсчет выдержки сначала. Если же что-то (часы или программа) "повиснет", то произойдет общий сброс МК, в том числе и инициализация часов. Причем после чтения данных из flash-памяти мы сможем это обнаружить: если помните, мы в кадр времени записывали байт сбоев (см. главу 12), в котором установленный бит 3 означал, что сброс произошел именно от сторожевого таймера.

Если встречаются процедуры, которые запрещают прерывания на длительный срок (у нас это была описанная в главах 12 и 13 операция чтения данных ReadFuliFlash), то перед их выполнением таймер нужно запрещать, а потом опять разрешать (листинг 14.10).
Листинг 14.10
proc_F2: ;F2 читать данные из памяти cli ;запрещаем прерывания /выключить WD:
wdr ; Reset WDT
in temp, WDTCR
ori temp, (1«WDCE) | (1«WDE)
out WDTCR, temp
ldi temp, (0«WDE) ; выключить WDT
out WDTCR, temp rcall ReadFullFlash ;читаем данные rcall Rclocklni /восстанавливаем часы /запускаем WDT обратно, 2 с
wdr /команда на сброс
ldi temp, (1«WDCE) | (1«WDE)
out WDTCR,temp
ldi temp, (1«WDP0) I (1«WDP1) | (1«WDP2) I (0«WDCE) | (1«WDE) out WDTCR,temp
sei /разрешаем прерывания — необязательно, уже есть /в ReadFullFlash rjmp Gcykle

Заметьте, что после такой длительной процедуры, как чтение массива внешней памяти, при использовании WDT можно вообще не разрешать прерывания (для этого придется убрать разрешение и из самой процедуры ReadFullFlash) — а вдруг мы что-то нарушили в работе? Тогда контроллер просто перезапустится с нуля, и работа восстановится (то же самое относится к обновлению значений времени в часах, см. главу 13). Универсальный способ принудительного перезапуска МК заключается в том, что после включения WDT запускают пустой бесконечный цикл.



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru