Если бы мы не связывались с кнопкой, то на этом можно было бы закончить — через 1 минуту после включения у нас измеритель уходит в «сон», из которого его можно вывести только выключением-включением питания или подачей сигнала Reset. Но мы хотим все делать грамотно, потому используем кнопку. Прерывание INTO тогда будет выглядеть так, как показано в листинге 17.4 (также не забудьте заменить в таблице прерываний во второй строке reti на rjmp EXT_INT0).
EXT_INT0:
clr temp
out GICR,temp ;запрещаем внешние прерывания
sbrs Flag,7 ;если были во сне, то больше ничего не делаем
reti
clr temp ;иначе готовимся ко сну
out TCCR1B,temp ;останавливаем таймер
clr temp ;чистим счетные регистры таймера
out TCNT1H,temp
out TCNT1L,temp
ldi temp,0b00001101 ;заново запускаем
out TCCR1B,temp
ldi count_min,7 ;на интервал 7,5 с
reti
Теперь у нас измеритель будет работать как задумывали: после включения через 1 мин. он уходит в режим энергосбережения, когда индикаторы гаснут, и потребление минимизируется. Если нажать на кнопку, то МК «проснется» и выполнит все процедуры после команды Sleep. Если ничего не делать, то через минуту измеритель опять «заснет». Если нажать до истечения этого срока на кнопку (но не ранее, чем через 7,5 с), то он «заснет» через 7,5 с после нажатия. В принципе таймер можно было бы и не останавливать перед засыпанием, но так мы более уверены, что он начнет отсчет с самого начала.
Время задержки вы легко можете регулировать, просто меняя число, которое загружается в регистры OCR1AH/L. Оно рассчитывается исходя из формулы: время задержки в секундах равно частоте кварца в герцах, деленному на коэффициент предварительного деления (1024) и на это число. Например, если вместо 29 297 загрузить 11 719, то пауза до засыпания по нажатию кнопки станет равной 3 с, а время работы сократится менее чем до полуминуты. Чтобы увеличить время «бодрствования» вдвое, команду sbrs count_min,3 в прерывании таймера нужно заменить на sbrs count_min,4.