;**************************************************************************

;**************************************************************************
.include "tn13def.inc"       	 		                      
;-----------------  Назначаем имена выводам микроконтроллера и регистрам --

;--------  присвоение имён выводам порта В  --------

.equ  Sound_out   =1      ;PB1  Output control led
.equ  SW          =3  	      ;PB3  Input Signal
.equ  Rele        =4   	      ;PB4  Output Rele

;---------   константы времени  ------------------ 
.equ  korrekt_3          =3929	    ;скорректированная константа
.equ  sekunda	  =8000  	   ;константа 
.equ  LED_ON	  =800       ;константа  
.equ  TIME1                =5
.equ  TIME2               =50

;-------------  назначение имён регистрам  --------------
.def  temp        =r16        ;r16    temprary register
.def  loop	         =r17	      ;Регистр счётчика циклов
.def  counter     =r18        ;Регистр хранения 
.def  flag           =r19
.def  cycl          =r20
.def  temp1       =r21
.def  temp2       =r22
.def  t1              =r23

;****************************************************************************
.cseg                         ;Выбираем сегмент памяти ;
.org 0
		rjmp     Reset
.org 0x0002				;прерывание по изменению логического уровня на PIN
						;External Interrupt Request 0
		rjmp	PCI0	; переход к программе обработки прерывания
;============================================================================  
;        macros  формирования временных интервалов  
;============================================================================

.macro	delay			    ;начало макроопределения
inc     @1 			;увеличиваем на единицу  содержимое  @1 
  mov     counter,@1	;приравниваем содержимое к r17
			;коэффициент повторения @2 раз (1-255)
K:		
mov     loop,counter;  r17 = r18
soul:
rcall	 Tik		;вызов подпрограммы звукового  сигнала
rcall	 Interval	                ;вызов  подпрограммы временной паузы 0,2 сек	
dec           loop		;обратный отсчёт
brne     soul		
di            flag,@2	                ;Загрузить множитель @2 на временную константу @0
Cycle:		                ;Формирование длительности работы таймера
ldi      XL,Low (@0)                    ;Загрузить младший байт константы времени
ldi      XH,high(@0)                  ;Загрузить старший байт константы времени
			;(максимальное значение @0 здесь не более  65535)
delay_: sbiw     XL,1		;Вычитаем единицу из слова 
brne     delay_		;не равен нулю, возвращаемся снова к метке delay_
dec      flag		;умножаем @2 количество раз на константу @0		
brne	 Cycle
dec      counter                       ;повторяем эту процедуру  @1 количества раз 
 brne	 K		;переход к метке K  по условию
		
.endm				         ;окончание макроса

;=============================================================================        
;     * инициализация *
;=============================================================================
Reset:  
clr cycl			;обнуляем содержимое счтчика отсчёта инервалов
cli 	 		;запрещаем  прерывание
;-----------------------------------------------------------------------------
ldi      temp,RAMEND	;инициализация стека ; 
out      SPL,temp  
;------------------   inicializaciya  PORTB   --------------------------------
ldi      temp,0b11110111 
 out      DDRB,temp		;конфигурация вх,вых.
	                                ;Назначаеем PВ3 входом,остальные выходами.	
Com    temp                            ;Инвертируем содержимое temp
out      PORTB,temp                ;Включаем подтяжку на PВ3                    
	
;==============================================================================
; * Главный программный цикл  * установка кнопкой количество интервалов таймера
;==============================================================================
main:	
clr	 temp
 sbic 	 PINB,SW         ;Опрашиваем ,разомкнуты ли контакты.кнопки
rjmp	 main            ;если  нет ,переходим  к началу цикла 
       

;-------------------------------------------------------------------------------------
		delay	 sekunda,temp,17; = 1.4 сек. один цикл  при установке таймера      		
;-------------------------------------------------------------------------------------
 inc      cycl		;начинаем прмой отсчёт вреенных интервалов
cikl: 
sbis PINB,SW	;проеряем состояние кнопки,если нажата ,продолжаем прямой отчёт  					
rjmp	 main	
dec	 cycl		;если отжата,прекращаем отсчёт и переходим к запуску таймера
cbi      PORTB,Rele	                ;Включаем реле начала  включения таймера
;-------------------------------------------------------------------------------------
time : 	delay	 korrekt_3, cycl,30  ;формирование суммарного заданного пользователем  
				;Времени  таймера = 5 min * cycl(количество интервалов)
;-------------------------------------------------------------------------------------
sbi      PORTB,Rele                   ;Выключаем реле ,таймер работу завершил.
Long:
ldi      temp2,20
H:
rcall    Tik
 dec      temp2
brne     H
stop:
sei			  ; разрешаем  прерывание
ldi     temp,(1<<PCIE)	 ; устанавливаем разрешение прерывания на PIN
out    GIMSK,temp		 ; по изменению уровня сигнала на PIN
ldi    temp,(1<<PCIF)	 ; устанавливаем флаг прерывания 
out   GIFR,temp		 ; по изменению сигнала на PB
ldi     temp,(1<<PCINT3)          ; разрешаем прерывание 
out    PCMSK,temp		 ; по изменению уровня на выводе PB3
End:   rjmp       cikl                 ;по окончанию цикла таймера переход в исходное состояние ;



;-------------------------------------------------------------------------------
; * * подпрограмма формирования задержки**
;-------------------------------------------------------------------------------
Tik: 
ldi	temp1,TIME1
 ldi	t1,TIME2      
;-------------------------------------------------------------------------------
Tik1:
                 sbi     PORTB,Sound_out	
Tik2:        dec     temp1
                brne    Tik2
                 dec     t1			    
	brne    Tik2
	cbi      PORTB,Sound_out	
	ret
;-------------------------------------------------------------------------------
; * подпрограмма временной задержки *
;-------------------------------------------------------------------------------
Interval:
        ldi      YL,Low  (LED_ON)  ;загрузить младший байт временной константы   
        ldi      YH,high (LED_ON)  ;загрузить старший байт временной константы
        on_:    sbiw     YL,10
        brne     on_
        ret

;-----------  подпрограмма обработки прерывания -----------------------------
PCI0:	
	 nop 							;пустая команда
	 reti