Задача, нужен таймер. Размер таймера зависит от проекта. И чтобы не
писать несколько вариантов, я сделал один. Что такое этот таймер?
Это, грубо говоря, счетчик из нескольких байтов, значение которого (зависит от задачи)
увеличивается или уменьшается на единицу в обработчике прерывания аппаратного таймера. Навскидку несколько вариантов:
; Вариант 1.
.dseg TIMER:
.equ TIMER_LENGHT = 4
.byte TIMER_LENGHT
.cseg
lds r16,TIMER
subi r16,-1 ; Вычитаем единицу, но так как число отрицательное,
sts TIMER,r16 ; то получается прибавление.
lds r16,TIMER+1
sbci r16,0 ; Вычитание с учетом переноса.
sts TIMER+1,r16
lds r16,TIMER+2
sbci r16,0
sts TIMER+2,r16
lds r16,TIMER+3
sbci r16,0
sts TIMER+3,r16
; Вариант 2.
clr RCLR
ser FLAGS
mov RSER
.dseg TIMER:
.equ TIMER_LENGHT = 4
.byte TIMER_LENGHT
.cseg
ldi r17,1
ldix TIMER
ld r16,X
add r16,r17 ; Прибавление единицы.
st X+,r16
ld r16,X
adc r16,RCLR ; Прибавление с учетом переноса.
st X+,r16
ld r16,X
adc r16,RCLR
st X+,r16
ld r16,X
adc r16,RCLR
st X+,r16
; Вариант 3. Размер таймера может быть разный.
clr RCLR
ser FLAGS
mov RSER
.dseg TIMER:
.equ TIMER_LENGHT = 4
.byte TIMER_LENGHT
.cseg
System_Timer:
ldix TIMER ; Указатель на счетчик.
ldi CNT,TIMER_LENGHT ; Запись размера таймера.
sec ; Предварительная установка флага переноса.
in IRSREG,SREG ; Сохранение SREG.
System_Timer_Cycle:
ld r16,X
out SREG,IRSREG ; Восстановление SREG.
adc r16,RCLR ; Прибавление с учетом переноса.
in IRSREG,SREG ; Сохранение SREG. Потому как
st X+,r16
dec CNT ; эта операция влияет на SREG
brne System_Timer_Cycle