В регистровую пару, загружалось число (константа) и производилось вычитание единицы из этого числа до тех пор, пока результат не сравняется с нолём. Вычитание разных констант, при определённой тактовой частоте микроконтроллера предполагало формирование разных интервалов времени.
1,125 с. получались при константе = 4500
0,2 с. при константе = 800
15 с. При константе = 60000
;***************************************************************************************
Подпрограммы формирования интервалов времени
;***************************************************************************************
;———————— 1.125 s ——————————-
Delay _1: ; T off «Led» = 1,125 s. время когда светодиод погашен
ldi XL,Low (4500) ; загружаем константу в нижний регистр регистровой пары Х
ldi XH,high (4500) ) ; загружаем константу в верхний регистр регистровой пары Х
del:
sbiw XL,1 ; вычитаем 1 из двухбайтного слова загруженного в регистровую пару Х
brne del ; если результат не равен нолю,снова переходим к метке ( del)
ret ; выход из этой подпрограммы
;——————————— 0.2s ——————————
Delay_2: ; ON «Led» =0,2 s. -формирование времени, когда светодиод горит.
ldi XL,Low (800)
ldi XH,high (800)
mm:
sbiw XL,1
brne mm
ret
;————————————— T = 15 Sek. ——————————————
Delay_15: ; формирование отрезка времени длительностью 15сек.
ldi XL,Low (60000)
ldi XH,high (60000)
del_:
sbiw XL,1
brne del_
ret
;**************************************************************************
Для этого я добавил новые записи в раздел присвоения имён переменных и констант, где для удобства при отладке, я смогу изменять их, если что, в одном только месте программы, которые будут подставляться соответствующими присвоению, именами, например:
;=============================================================
.equ LED_ON =800 ;константе (0,2c) присвоили имя « LED_ON »
.equ LED_OFF =4500 ;константе (1,125c.) присвоили имя – «LED_ OFF »
.def counter =r18 ;Регистру повторения количества раз *delay* имя — « counter »
;=============================================================
Для того, чтобы все три подпрограммы объединить в одно выражение, надо создать макрос. Дадим ему символическое имя — «delay » (задержка). Так же улучшаем характеристики прежней подпрограммы для формирования больших временных интервалов, мы добавляем ещё коэффициент умножения (на сколько надо умножить полученный временной интервал с занесённой константой времени, чтобы получить ещё большие отрезки времени. Этот коэффициент — число на которое надо умножить временной интервал, полученный нами, с использованием соответствующей константы. Эта величина должна быть в пределах от 1 до 255 (255 -максимальное однобайтное число)
И вот что у меня получилось:
; macros delay
;=============================================================
.macro delay ; присваиваем имя макросу — « delay »
Ldi counter,@1 ; здесь @1- это коэффициент повторения макроса K раз(1-255)
K:
ldi XL,Low (@0) ;Загрузить младший байт константы времени
ldi XH,high(@0) ;Загрузить старший байт константы времени
delay_:
sbiw XL,1; вычитаем единицу из двухбайтного слова загруженного в регистровую пару Х
brne delay_
dec counter
brne K
.endm ; конец макроса
;=============================================================
Важный момент! Макрос надо располагать в самом начале программы.
Компилятор ассемблера проходя с начала до конца, читая нашу программу, усваивает условия оговоренные макросом в начале, точно так же, как и присвоение имён переменных и констант и остальные моменты, которые оговариваются в начале. Если мы расположим кусок подпрограммы макроса в конце программы, то он работать не будет и будет воспринят ассемблером, как ошибка.
Вместо трёх получилось одно универсальное выражение. Сравните визуально, сколько сократилось строк в тексте программы.
Теперь, если я захочу сформировать временной интервал, то вызываю этот макрос и выглядит эта запись так:
;———————————————————————————————————
delay PAUSE, 3
;———————————————————————————————————
Где delay — это имя макроса, PAUSE — это имя присвоенное нами константе (15 c.). В макросе таких величин-констант может быть записано в строке через запятую до 10-ти возможных (всё зависит от того, какой макрос мы придумаем).
В результате мы получаем интервал времени равный 45с (15с. х 3).
Пример использования макроса в проекте «Выключатель освещения в подъезде на микроконтроллере AVR«. В продолжении, пример обоих программ, модель в Proteus для наглядности работы таймера, можно сравнить, посмотреть, проанализировать просматривая содержимое регистров нашей программы.