;**** Частота 50 Гц, g=0,025 с помощью T/C1 *****************************
;*
;* На выходе OC1A микроконтроллера AT90S8515 получаем выходные импульсы
;* с частотой 50 Гц и коэффициентом заполнения g = 0,025.
;*
;* Тактовая частота микроконтроллеров AVR: 4 МГц (Стандарт STK200)
;*  
;***************************************************************************
.nolist
.include "8515def.inc"
.list

.def	STAT	= r15	; Регистр для хранения состояния главной программы
.def	WorkH	= r16	; Рабочий регистр для главной программы
.def	WorkI	= r17	; Рабочий регистр для прерывания от таймера
.def	AddLo	= r18	; Вспомогательный регистр для прибавления константы

.equ	Impuls	= 250	; Число тактовых сигналов, соответствующее импульсу
.equ	Pause	= 9750	; Число тактовых сигналов, соответствующее паузе

Reset:
rjmp Initial	; Переход к части инициализации
reti	; Внешнее прерывание 0 (не используется)
reti	; Внешнее прерывание 1 (не используется)
reti	; Прерывание по захвату (не используется)
Timer1CompA:		; Прерывание CompareA для AT90S8515
in   STAT,SREG	; Сохраняем флаги главной программы
in   WorkI,TCCR1A	; Регистр управления А счетчика T/C1
sbrs WorkI,COM1A0	; Пропускаем следующую команду, если Com1A0 = 1
rjmp TC1	; Пропускаем следующую команду, если Com1A0 = 0
cbr  WorkI,1<<COM1A0	; При следующем прерывании OC1A -> 0
out  TCCR1A,WorkI	; Сохраняем новое значение
in   AddLo,OCR1AL	; Младший байт OCR1A
subi AddLo,Low(-Impuls)	; Прибавляем младший байт значения длительности импульса
in   WorkI,OCR1AH	; Старший байт OCR1A
sbci WorkI,High(-Impuls)	; Прибавляем старший байт значения длительности импульса
rjmp IntEnde
TC1:
sbr  WorkI,1<<COM1A0	; При следующем прерывании OC1A -> 1
out  TCCR1A,WorkI	; Сохраняем новое значение
in   AddLo,OCR1AL	; Младший байт OCR1A
subi AddLo,Low(-Pause)	; Прибавляем младший байт значения длительности импульса
in   WorkI,OCR1AH	; Старший байт OCR1A
sbci WorkI,High(-Pause)	; Прибавляем старший байт значения длительности импульса
IntEnde:
out  OCR1AH,WorkI	; Назад – старший байт нового значения
out  OCR1AL,AddLo	; Назад – младший байт нового значения
out  SREG,STAT	; Восстанавливаем старые флаги
reti	; Выход из обработки прерывания CompareA

Initial:	; Инициализация регистра ввода/вывода
ldi  WorkH,High(RamEnd)
out  sph,WorkH
ldi  WorkH,Low(RamEnd)
out  spl,WorkH	; Инициализируем стек
clr  WorkH	; Все разряды = 0
out  PortD,WorkH	; Вывод в порт D
ldi  WorkH,$20	; Разряд 5 - в 1, остальные – в 0
out  DDRD,WorkH	; OC1A (PD5) - выход, остальные - входы
ldi  WorkH,High(Pause)	; Старший байт значения паузы
out  OCR1AH,WorkH	;   в старший байт регистра сравнения A
ldi  WorkH,Low(Pause)	; Младший байт значения паузы
out  OCR1AL,WorkH	;   в младший байт регистра сравнения A
ldi  WorkH,$C0	; OC1A -> 1
out  TCCR1A,WorkH	; Сохраняем новое значение
ldi  WorkH,$02	; Входной такт T/C1 = такт сист. синхр./8
out  TCCR1B,WorkH	; Запускаем T/C1
ldi  WorkH,$40
out  TIMSK,WorkH	; Разрешаем прерывание CompareA
sei	; Общее разрешение прерываний (разряд I)
Haupt:
rjmp Haupt	; Главная часть программы: ожидаем возникновения прерывания
