Листинг 17.1

;++++++++Set Timer 1

       ldi temp,high(292 97)

       out OCR1AH,temp

       ldi temp,low(2 9297)

       out OCR1AL,temp

       ldi temp,0b00001101

       out TCCR1B,temp  ;1/1024; очистить после совпадения

       ldi temp,(1<  ;разреш. прерывания

            ;по совпадению для Timer 1 и переполнению Timer 0

       out TIMSK,temp

Переключающий режим для вывода PDS-OC1A здесь мы не используем. Кроме этого, введем переменную count_min, с помощью которой будем считать интервалы в 7,5 с. В секции объявления переменных добавим:

def count_min = r23  ;счетчик 7,5-секундных интервалов

А в секции начальных установок его не забудем обнулить:

clr count_min

Далее введем специальный флаг sleep (пусть будет бит 7 в регистре Flag), который будет сигнализировать о режиме. Если этот бит установлен — пора «спать», если обнулен — работаем, как ни в чем не бывало. По умолчанию он обнулен (см. секцию «начальная установка переменных») и нам ничего не грозит, если мы вставим в основной цикл запуск режима энергосбережения по схеме, согласно листингу 17.2.

Листинг 17.2

Gcykle:

    sbrs Flag,7  ;если бит 7 установлен, то засыпаем

гjmp Gcykle  ;иначе бесконечный цикл

cli  ;на всякий случай запрещаем прерывания; все порты на вход, и нули в разряды, кроме PortD,6

    clr temp

    out DDRB,temp

    out DDRC,temp

    out DDRD,temp

    out PortB,temp

    out PortC,temp

    ldi temp,0b01000000  ;выключение питания на всякий случай

    out PortD,temp

    ldi temp,0b11100000  ;разрешение Sleep, режим Standby прерывание по уровню

    out MCUCR,temp

    ldi temp,(1<  ;разрешение INTO

    out GICR,temp

sei  ;разрешаем прерывания

Sleep  ;наконец, спим

    cbr Flag, $80  ;по выходу из сна сбрасываем флаг sleep

    clr count_min  ;отсчет времени

;сначала установка портов вход-выход обратно

cli  ;на всякий случай запрещаем прерывания

    ldi temp,0b00111111  ; разряды out DDRB,temp

    ldi temp,0b01111111  ; сегменты out DDRC,temp

    ldi temp,0b11000000  ; знак минус и питание

    out DDRD,temp

    clr temp

    out PortD,temp  ;включить аналоговое питание

    out MCUCR,temp  ;запрещаем режим Sleep

    out TCNT1H,temp  ;очищаем счетные регистры таймера

    out TCNT1L,temp

    ldi temp,0b00001101  ; запускаем таймер

    out TCCR1B,temp  ;1/1024 очистить после совпадения

sei  ;разрешаем прерывания

rjmp Gcykle  ;бесконечный цикл

Теперь самое сложное: разобраться с прерываниями и установкой флага sleep. Не забудьте заменить reti на rjmp TIM1_COMPA в таблице прерываний, в строке для прерывания Timer1 Compare А (шестое сверху, не считая RESET). Прерывание таймера иллюстрирует листинг 17.3.

Листинг 17.3

ТIМ1_СОМРА:

   inc count_min

   cpi count_min,1  ;через 7,5 с разрешаем INTO

   brne schet_time

   ldi temp,(1<  ;разрешение INTO

   out GICR,temp  ;GIMSK и GIGR — синонимы

schet_time:  ;здесь отсчет времени

   sbrs count_min,3  ;если бит 3=1, то прошло 8 интервалов =1 мин

reti  ;иначе выходим

   clr count_min  ;в след, раз — сначала

   sbr Flag,$80  ;устанавливаем бит sleep

   clr temp  ;останавливаем таймер

   out TCCR1B,temp

reti  ;выходим

Перейти на страницу:

Поиск

Похожие книги