І]
"РЛ" - НАЧИНАЮ Щ ИМ
І
timerO:
check:
; далее все, как было раньше
mov
TMOD, #1
setb
ЕА
setb
ETO
setb
TFO
setb
TRO
jmp
$
; режим работы ТАтегО задаем = 1
; разрешаем все прерывания вообще
; разрешаем прерывания от ТллпегО
; искусственно вызываем прерывание
; запускаем ТАтегО
; ничего не делаем больше
push
ACC
; сохраним аккумулятор
push
PSW
; сохраним и слово состояния
mov
ТН0, #InitTH
; заносим начальное значение ТН0
mov
TL0, #InitTL
; заносим начальное значение
ТЪО
; уменьшаем счетчик и проверяем результат на 0
mov
A, CounterL
; начнем с младшего байта
clr
C
; надо сбросить флаг переноса!
subb
A, #1
; уменьшим на 1
mov
CounterL, A
; сохраним новое значение мл. байта
jnc
check
; если не было переноса - проверим,
; нужное кол-во прерываний?
; произошло переполнение при уменьшение младшего байта
; значит, надо уменьшить и старший байт
; (вычитание "столбиком")
dec
CounterH
; уменьшаем ст.байт
не прошло ли уже
; проверим, не истекло ли нужное кол-во прерываний
orl
A, CounterH
; А = CounterL OR CounterH
jnz
int_exit
; если А не равно нулю - не истекло!
cpl
LED
; переключим светодиод
; занесем в счетчик начальное Значение
mov
CounterL, #Low(IntNums)
; сначала младший байт
mov
CounterH, #High(IntNums)
; а затем - старший
int exit:
; выход
pop
PSW
pop
ACC
reti
; восстановим слово состояния
; восстановим аккумулятор
; обработчик завершен
Как видите, усилий уже немного больше, но и резуль-
тат не плох! Теперь, меняя значение IntNums, мы легко
перекроем практически весь разумный диапазон мига-
ния светодиода (максимальная длительность свечения
достигнет почти часа!).
Снова обращаю ваше внимание на некоторые тонкости.
Во-первых, теперь пришлось использовать стек для
сохранения аккумулятора и регистра PSW. Не смотря на
то, что наша основная программа ничего не делает, т.е.
не использует ни аккумулятора, ни флагов PSW, привы-
кать поступать именно так, я думаю, надо. Сразу возьми-
те себе за правило:
обработчик прерывания не должен
никогда изменять контекст основной программы
(контекст
-зто все ресурсы, которыми программа пользуется). Если
требуется сэкономить ячейки стека, надо использовать,
например, незадействованные регистры.
Во-вторых, обратите внимание, как я проверяю на
равенство нулю двухбайтное число: не сравниваю его
байты по очереди с нулем (потребовалось бы гораздо
больше команд), а выполняю логическое ИЛИ над его
байтами, а уже результат проверяю на ноль - так го-
раздо оптимальнее. И если вам придется проверять на
ноль трех-, четырех- и т.д. -байтные числа, поступайте
аналогично!
В-третьих, заметьте, что для задания начального зна-
чения счетчика таймера я использую “искусственный вы-
зов прерывания” путем программной установки флага
ТЕО: ведь в обработчике мы все равно заносим в счет-
чик начальное значение, а значит, нет необходимости
повторять те же самые команды на этапе начальной ини-
циализации. Кстати, не будет никакой беды, если про
начальную инициализацию счетчика мы вообще забу-
дем - после запуска таймер первый раз переполнится
через несколько больший интервал, но все последую-
щие переполнения пойдут четко по задуманному. Конеч-
но, такое пренебрежение начальными параметрами до-
пустимо не всегда - это надо учитывать в каждом конк-
ретном случае.
Наконец, попробуйте самостоятельно (домашнее за-
дание №3) решить еще более сложную задачу: заставьте
мигать светодиод не со скважностью 2, а с произволь-
ной, причем частота мигания должна остаться 1 Гц.
Продолжение в №10/2007
Радиолюбитель - 0 9 /2 0 0 7 [)
45
предыдущая страница 45 Радиолюбитель 2007-09 читать онлайн следующая страница 47 Радиолюбитель 2007-09 читать онлайн Домой Выключить/включить текст