		.include "tn13def.inc"
		
		.def temp=r16
		.def temp2=r17
		.def window=r20		;окно фильтра
		.def phi1=r21		;угол упр первого канала
		.def phi2=r22		;угол упр второго канала
		.def phi=r23		;счетчик текущего угла
		.def tim_sync=r24	;таймер регистрации синхронизации	
		.def bitreg=r25		;регистр флагов
		.def tim_res=r19	;таймер до сброса состояния

;bitreg	(флаги)
		.equ trig_sw=$0		;триггер состояния один/два канала
		.equ trig_on=$1
		.equ trig_off=$fe

		.equ sync_sw=$1		;наличие синхронизации
		.equ sync_on=$2
		.equ sync_off=$fd

		.equ pri_sw=$2		;признак начала полупериода
		.equ pri_on=$4
		.equ pri_off=$fb

		.equ tr_sw=3		;триггер таймера синхронизации
		.equ tr_on=$8
		.equ tr_off=$f7
/*
		.equ _sw=4
		.equ _on=$10
		.equ _off=$ef

		.equ _sw=5
		.equ _on=$20
		.equ _off=$df

		.equ _sw=6
		.equ _on=$40
		.equ _off=$bf

		.equ _sw=7
		.equ _on=$80
		.equ _off=$7f
*/		
;portb
		.equ in_sync=0		;вход синхронизации
		.equ chanel1=1		;выход канала 1
		.equ chanel2=2		;выход канала 2
		.equ test1=3		;своб/тестовая ножка
		.equ test2=4		;своб/тестовая ножка

;const
		.equ tau=$10		;время таймера синхронизации
		.equ min_phi=$18	;мин угол управления
		.equ max_phi=$a0	;макс угол управления
		.equ phi_beg=$90

;memory:
		.equ first=$61		;проверочные ячеки
		.equ second=$62


		rjmp begin

;overflow tim0				прерывание по переполнению таймера0
		.org $003
		push temp2
		push temp
		in temp,sreg
		push r16
		in temp,tcnt0		
		subi temp,-200 		;период прерываний 40мкс
		out tcnt0,r16
		
		in temp,pinb		;читаем вход
		sbrc temp,in_sync
		sec
		sbrs temp,in_sync
		clc
		rol window			;задвигаем в окно фильтра справа(налево)
	
		mov temp,window	
		andi temp,$07		;отделяем мл три байта
		cpi temp,$5			;ххххх101 - была помеха в ноль
		breq m5_7			;заменяем на ххххх111
		cpi temp,$2			;ххххх010 - была помеха в единицу
		breq m2_0			;заменяем на ххххх000

back_filt:	
		cpi window,$1f		;проверяем окно на 0001111 - фронт синхронизации
		breq rise_sync		
		cpi window,$f8		;проверяем окно на 1111000 - срез синхронизации
		breq fall_sync

back_sync:

		cbi portb,chanel1	;выключ управление (длит импульса упр - один период прерыв)
		cbi portb,chanel2
		inc phi				;добавл сч угла
		brne sync_n			;если переполнился - авария
		andi bitreg,sync_off;снимаем флаг наличия синхр
		rcall switch		;п/программа таймера и переключения

sync_n:
		sbrs bitreg,sync_sw	;пров флаг синхронизации
		rjmp exit			;нету - нет и импульсов
		cpi phi,max_phi		;пров на макс угол
		brcc exit			
		cp phi,phi1			;пров задание канала 1
		brne next
		sbi portb,chanel1	;уст управление канала
next:	cp phi,phi2			;пров задание канала 2
		brne exit
		sbi portb,chanel2	;уст упр канала 2

exit:
		
		sbrc bitreg,trig_sw	;на контр ножку выводим триггер состояния
		sbi portb,test2
		sbrs bitreg,trig_sw
		cbi portb,test2
		
;		sbrc phi1,0;bitreg,tr_sw
;		sbi portb,test1
;		sbrs phi1,0;bitreg,tr_sw
;		cbi portb,test1


		pop temp
		out sreg,temp
		pop temp
		pop temp2
		reti

;синхронизация
rise_sync:
fall_sync:
		clr phi				;обнуляем сч угла
		ori bitreg,pri_on	;уст флаг начала п/периода
		ori bitreg,sync_on	;уст флаг синхронизации
		rcall switch		;пп таймера и управления
		rjmp back_sync

m5_7:	ori window,$07
		rjmp back_filt

m2_0:	andi window,$f8
		rjmp back_filt 

;пп переключателя и таймера
switch:
		sbrs bitreg,sync_sw	;по уст флагу синхр - таймер ++
		rjmp dec_tm			;по снятому флагу - таймер --

inc_tm:	ldi tim_res,$60		;восст время до сброса
		cbi portb,test1		;сбр контр ножку
		sbrc bitreg,tr_sw	;триггер таймера
		rjmp exit2
		ldi r16,tau			;время до переключения
		add tim_sync,r16	;добавл
		brcc exit2			;уже переполнилось?
		ser tim_sync		;таймер в макс
		ori bitreg,tr_on	;уст триггер таймера
		rjmp save

dec_tm:	sbrs bitreg,tr_sw	;триггер таймера
		rjmp chek_tim
		subi tim_sync,tau	;вычит
		brcc exit2			;довычитали?
		clr tim_sync		;обнул таймер
		andi bitreg,tr_off	;сним флаг
		ldi temp,trig_on
		eor bitreg,temp		;инвертируем триггер состояния
			
		ldi phi1,phi_beg	;нач угол в канал 1
		ser phi2			;канал 2 в зону инверсных углов
		
saving:
		sbrs bitreg,trig_sw	;пров триг состояния
		rjmp trig_of
		
		ldi temp,$13		;уст контрольные байты
		ldi temp2,$89
save:		
		sts first,temp		;запоминаем в ОЗУ для стартовго контроля
		sts second,temp2
exit2:	
		ret

chek_tim:
		dec tim_res			;пров таймер паузы
		brne exit2			
		sbi portb,test1		;уст контр ножку
trig_of:
		clr temp			;обн контр байты
		clr temp2		
		rjmp save

;==================================================

begin:	ldi temp,ramend		;стек
		out spl,temp
		ldi temp,0		
		out portb,temp		;инит порта
		ldi temp,$fe
		out ddrb,temp		;направл порта
		ldi temp,$02		;таймер ск/8
		out tccr0b,temp
		out timsk0,temp		;прерыв по переполнению
		sei					;разреш пррывания
		inc phi1			;так нада
		inc phi2

chek:	cpi phi1,min_phi	;если угол упр не там
		brcs phi1_n
		ser phi1			;выключ канал

phi1_n:
		cpi phi2,min_phi	;то же для канала 2
		brcs phi2_n
		ser phi2

phi2_n:						;пров контр байты
		lds temp,first		;первый
		cpi temp,$13		;проверка
		brne res_trg		;нет - сбр триггер сост
		lds temp,second		;второй 
		cpi temp,$89		;проверка
		brne res_trg		;на сброс триггера сост
		
		ori bitreg,trig_on	;уст триггер сост

main:	andi bitreg,pri_off	;сбр флаг начала периода

loop:	sbrs bitreg,pri_sw	;пров
		rjmp loop			;ждем
		cpi phi1,min_phi	;не минимальный ли угол в канале 1?
		brcc dec_phi1		;нет - убавим

next_ch:		
		sbrs bitreg,trig_sw ;пров триг состояния
		rjmp main
		cpi phi2,min_phi	;не миним ли угол в канале 2
		brcc dec_phi2		;нет- убавим
		rjmp main

dec_phi2:
		dec phi2			;убавление угла канала 2 - увелич напряжение
		rjmp main

dec_phi1:
		dec	phi1			;убавление угла канала 1 - увелич напряжение
		rjmp next_ch
		
res_trg:					;сброс триг состояния
		andi bitreg,trig_off
		ser phi2			;выключ канал 2
		rjmp main

;все!
