.include "D:\AVR Tools\AvrAssembler\Appnotes\8535def.inc"
.cseg
.def mes=r17
.def den=r18
.def chas=r19
.def min=r20
.def sek=r27
; R16 - временный регистр
; R21 - регистр работы с UART
; R22 - указатель на нужное расписание в EEPROM
; R23 - для флагов
; R24 - указатель на текущий приборорежим
; R25 - значение из памяти
; R26 - флаг выводного порта (N прибора > 8)
;-------------
.org $000
rjmp main
.org $004
rjmp T2ovf
.org $00b
rjmp uart_dre
;-------------
uart_dre:       ; Обр-к прерывания UART
in r21, udr     ; --Задай UDR--
reti
;-------------
T2ovf:      ; Обр-к прерывания таймера (минуты)
in r23, sreg
push r23
inc r28
cpi r28, 0x80
brne goback
ldi r28, 0
inc sek
cpi sek, 60
brlo goback
ldi sek, 0       ; Корректировка переходов
inc min
cpi min, 60
brlo goback
ldi min, 0
inc chas
cpi chas, 24
brlo goback
ldi chas, 0
inc den
cpi den, 32
brlo goback
ldi den, 1
inc mes
cpi mes, 13
brlo goback
ldi mes, 1
goback:
pop r23
out sreg, r23
reti
;-------------
main:
;Инициализация
ldi r16, 0xdf
out spl, r16   ; Стек
rcall clear    ; Очистка EEPROM
ldi mes, 1     ; Начальное время
ldi den, 1
ldi chas, 0
ldi min, 0
ldi sek, 0
ldi r28, 0
ldi r21, 0
ldi r24, 0
sei            ; Разрешение прерываний
ldi r16, 25
out ubrr, r16  ; Скорость UART = 9600
ldi r16, 8
out assr, r16  ; Таймер - от кристалла
ldi r16, 0xff
out ddra, r16  ; Порт А на вывод
ldi r16, 3
out ddrb, r16  ; Биты 0 и 1 порта Б на вывод
ldi r16, 144
out ucr, r16   ; UART на чтение
ldi r16, 64
out timsk, r16 ; Разрешение прерывания таймера
ldi r16, 1
out tccr2, r16  ; Настройка и запуск таймера
;Работа
Wait:          ; Цикл ожидания
rcall check
cpi r21, 0      ; Задали ли режим настройки
breq wait      ; --Установи USR->RXC--

cpi r21, 1
breq rej1       ; Режим корректировки даты (31->1)
cpi r21, 2
breq rej2       ; Режим задания времени
cpi r21, 3
breq rej3       ; Режим задания расписания
rjmp wait
;------------
Rej1:           ; Подпрога корректировки 31->1
ldi r21, 0
inc den
cpi den, 32     ; Корректировка переходов
brlo wait
ldi den, 1
inc mes
cpi mes, 13
brlo wait
ldi mes, 1
rjmp wait
;------------
Rej2:           ; Подпрога установки времени
ldi r21, 70
mes2:           ; Ожидание приёма месяца
cpi r21, 70
breq mes2
mov mes, r21
ldi r21, 70
den2:           ; Ожидание приёма дня
cpi r21, 70
breq den2
mov den, r21
ldi r21, 70
chas2:          ; Ожидание приёма часа
cpi r21, 70
breq chas2
mov chas, r21
ldi r21, 70
min2:           ; Ожидание приёма минут
cpi r21, 70
breq min2
mov min, r21
ldi r21, 0
rjmp wait
;-------------
Rej3:       ; Подпрога установки расписания вкл/выкл
ldi r21, 70
nom3:           ; Ожидание приёма номера прибора
cpi r21, 70
breq nom3
mov r22, r21
subi r22, 1
lsl r22         ; Умножение на 8 (3 строки)
lsl r22
lsl r22
out eearl, r22  ; Указатель на нужный прибор
;----------
ldi r16, 1     ; Счётчик записи расписания
ldi r21, 70
vvod:           ; Ожидание ввода элемента
cpi r21, 70
breq vvod
out eedr, r21   ; Значение - в регистр данных
ldi r21, 6
out eecr, r21   ; Записать в EEPROM
inc r22
ldi r21, 0
out eecr, r21
out eearl, r22  ; Увеличить указатель
ldi r21, 70
inc r16         ; Увеличить счётчик
cpi r16, 9      ; Оба ли расписания записаны
brne vvod
ldi r21, 0
rjmp wait
;----------
check:         ; Подпрога проверки расписаний
cpi r24, 80    ; Последний ли прибор
brlo cont
ldi r24, 0     ; Сначала
cont:           ; Проверка расписания прибора
rcall vvod1
cp r25, mes
brne back3
rcall vvod1
cp r25, den
brne back2
rcall vvod1
cp r25, chas
brne back1
rcall vvod1
cp r25, min
brne back0
RCALL TRY     ; Звонок!!!
ret

vvod1:          ; Подпрога чтения значений из памяти
out eearl, r24
ldi r16, 1
out eecr, r16
in r25, eedr    ; В R25 значение
inc r24
ret

back3:      ; Блок корректировки на след. прибор
inc r24
back2:
inc r24
back1:
inc r24
back0:
ret
; ПРОЦЕДУРА ЗВОНОК
TRY:
push r24
subi r24, 4
ldi r26, 0       ; Приборы 1-8
cpi r24, 0x40
brlo prta
subi r24, 0x40   ; Приборы 9 или 10
ldi r26, 0x0f
prta:
lsr r24        ; Корректировка адреса
lsr r24
lsr r24
brlo vikl      ; Вкл/выкл?
rcall vibor
cpi r26, 0      ; Выбор порта
breq prta1
in r24, portb   ; Вкл порт Б
or r24, r16
out portb, r24
pop r24
ret
prta1:          ; Вкл порт А
in r24, porta
or r24, r16
out porta, r24
pop r24
ret

vikl:
rcall vibor
cpi r26, 0       ; Выбор порта
breq prta2
in r24, portb    ; Выкл порт Б
com r16
and r24, r16
out portb, r24
pop r24
ret
prta2:           ; Выкл порт А
in r24, porta
com r16
and r24, r16
out porta, r24
pop r24
ret
;Процедура выбора пина порта
vibor:
ldi r16, 1
cikl:
cpi r24, 0
breq next
dec r24
lsl r16
rjmp cikl
next:
ret
; Процедура очистки области расписаний EEPROM
clear:
ldi r16, 0
out eedr, r16
ldi r21, 6
cl1:
out eearl, r16
out eecr, r21
inc r16
cpi r16, 80
brne cl1
ret