.include "c:\avr\avrasm\appnotes\tn2313def.inc"

	.def	temp	=r16
	.def	temp1	=r17
	.def	temp2	=r18
	.def	temp3	=r19
	.def	temp4	=r20
	.def	Per	=r21
	.def	tim	=r22
	.def	wei	=r23
	
	.CSEG
	.org 0	
		rjmp	Reset		; Прерывание Reset 		
		rjmp	INT_0		; Внешнее прерывание Int0	
		RETI			; Внешнее прерывание Int1
		RETI			; Таймер/счётчик 1 захват
		RETI			; Таймер/счётчик 1, совпадение, канал A
		RETI			; Таймер/счётчик 1, прерывание по переполнению
		RETI			; Таймер/счётчик 0, прерывание по переполнению
		RETI			; Прерывание UART приём завершён
		RETI			; Прерывание UART регистр данных пуст
		RETI			; Прерывание UART передача завершена
		RETI			; Прерывние по компаратору
		RETI			; Прерыание по изменению на любом контакте
		RETI			; Таймер/счётчик 1, совпадение, канал B
		rjmp  	tm0a		; Таймер/счётчик 0, совпадение, канал A
		RETI			; Таймер/счётчик 0, совпадение, канал B

Reset:					;тело программы
          		ldi Temp,RamEnd		;инициализация стека
          		out SPL,Temp

		ldi per,0
;***********************************************
; Настройка портов
;***********************************************

		ldi Temp,0b11111111		;Порт B На вывод
          		  out DDRB,Temp
		  out PORTB,Temp

		ldi Temp,0b00000000		;Порт D на ввод
		  out DDRD,Temp
		  out PORTD,Temp

;***********************************************
; Настройка прерывания INT_0
;***********************************************       

					
					
		ldi Temp,0b00000011		; в MCUCR надо выставить 2 младших бита, триггер срабатывания прерывания
					; 00 - низкий уровень, 01 - зарезервировано, 10 - по спаду, 11 - по фронту
		  out MCUCR,Temp		;установка триггера

		ldi Temp,0b01000000	
		  out GIMSK,Temp		;разрешение прерывания int0

		ldi Temp,0b01100000		;сброс флагов прерываний
		  out EIFR,Temp		


;***********************************************
; Настройка таймера
;***********************************************       


		ldi Temp,0b00000010   	;тактовый сигнал = CK/8
        		  out TCCR0B,Temp

         		ldi Temp,0xFA         		;инициализация компаратора таймера 0 канала А
      		  out OCR0A,Temp       	
          		sei                   		;разрешить прерывания	


;***********************************************
; Основная программа
;***********************************************

		
op2:
		sbrc wei,1			;сравнение первого разряда константы per т.е. 0b00000001
		  rjmp op2			;если первый разряд сброшен (0), перейти по мете op2
		  rcall n1			;если первый разряд установлен (1), перейти по метке n1 с возвратом
		rjmp op2


;***********************************************
; Обработка прерывания INT_0
;***********************************************


INT_0:		
		sbrc per,1			;сравнение первого разряда константы per т.е. 0b00000001
		  rjmp m1			;если первый разряд сброшен (0), перейти по мете m1
		  rjmp m2			;если первый разряд установлен (1), перейти по метке m2

		cli			;запретить прерывания

m1:		ldi Temp,0b00000010		;прерывание по спаду
		  out MCUCR,Temp	

		ldi Temp,0b00000001  	;разрешить прерывание компаратора   
		  out TIMSK,Temp

		sei			;разрешить прерывания

     		ldi Temp,0            	       	;обнуление таймера
         		  out TCNT0,Temp

	reti
m2:		
		cli			;запретить прерывания		

		ldi per, 0b00000001

		ldi Temp,0b00000011		;прерывание по фронту
		  out MCUCR,Temp	

		mov   tim,TCNT0		;копируем значение 0 таймера в регистр tim

		sei			;разрешить прерывания

     		ldi Temp,0            	       	;обнуление таймера
         		  out TCNT0,Temp

		   cpi tim,0b00111101		;Сравниваем регистр tim со значением 61 (00111101)
		      brlo m3		;Если tim < 61 идем по метке m3
		      rjmp m4		;иначе переход на m4

m3:		ldi Temp,0b00000000		;отключаем все светодиоды
		   out portb,temp
		sleep			;режим сна

m4:		cpi tim,0b00111101		;Сравниваем регистр tim со значением 61 (00111101)
		   brlo m5			;Если tim < 121 идем по метке m5
		   rjmp m6			;иначе переход на m6

m5:		ldi wei, 0b00000001		
		sbi PORTB,1		;отключаем  первый светодиод
		sbi PORTB,2		;отключаем  второй светодиод

m6:		cpi tim,0b10110101		;Сравниваем регистр tim со значением 181 (10110101)
		   brlo m7			;Если tim < 181 идем по метке m7
		   rjmp m8			;иначе переход на m8

m7:		cbi PORTB,1		;зажигаем  первый светодиод

m8:		cpi tim,0b11110001		;Сравниваем регистр tim со значением 241 (10110101)
		   brlo m9			;Если tim < 241 идем по метке m9
		   rjmp m0			;иначе переход на m0

m9:		cbi PORTB,2		;зажигаем  второй светодиод	
	
m0:		cbi PORTB,3		;зажигаем  третий светодиод			

	reti
;***********************************************
; Обработка прерывания компаратора по таймеру
;***********************************************
tm0a:		cbi PORTB,4		;зажигаем четвёртый проверочный светодиод (если он зажигаеся значит не правильно настроен компаратор)
		reti 
		
;***********************************************
; подпрограмма маячков
;***********************************************
n1:
		cbi PORTB,7
		cbi PORTB,6
		cbi PORTB,4
		rcall wt
		sbi PORTB,4
		rcall wt
		cbi PORTB,4
		rcall wt
		sbi PORTB,4
		rcall wt
		cbi PORTB,4
		rcall wt
		sbi PORTB,4

		rcall wt2

		cbi PORTB,5
		rcall wt
		sbi PORTB,5
		rcall wt
		cbi PORTB,5
		rcall wt
		sbi PORTB,5
		rcall wt
		cbi PORTB,5
		rcall wt
		sbi PORTB,5
ret
;***********************************************
; подпрограмма задержки
;***********************************************

wt:  		ldi Temp1,4
		ldi Temp2,65
		ldi Temp3,1

Loop:		dec Temp1
		brne Loop

		dec Temp2
		brne Loop

		dec Temp3
		brne Loop

		ret

Wt2:		ldi Temp1,0
		ldi Temp2,0
		ldi Temp3,5

Loop2:		dec Temp1
		brne Loop2

		dec Temp2
		brne Loop2

		dec Temp3
		brne Loop2

		ret
wt3:
		ldi Temp1,180
		ldi Temp2,2

Loop3:		dec Temp1
		brne Loop3

		dec Temp2
		brne Loop3

		ret

wt4:		
		ldi Temp1,65
		ldi Temp2,1

Loop4:		dec Temp1
		brne Loop4

		dec Temp2
		brne Loop4
	

		ret