/* таймер для управления светом и вентилятором
    Attiny15
    
 */   

.include "tn15def.inc"
    
.equ out_lamp = 3;  выход управления освещением    
.equ out_vent = 4;  выход управления вентилятором   

.def flags  = R22; регистр флагов
    .equ power = 0; flags для фильтрации помех
    .equ vent = 1; flags,1 флаг включения вентилятора
.def mode = R23  ; переменная для хранения режима работы  01- лампа, 10 - вентилятор, 11 - лампа и вентилятор 
    .equ vent_mode = 0;mode,0 вентилятор
    .equ lamp_mode = 1;mode,1 лампа
    
.def delay = R19 ; переменная для хранения времемени задержки до 22 мин
.def delay_H = R20; переменная для хранения времени задержки выше 22 мин
.def ms_delay = R21 ; переменная для хранения времени задержки выключения выключателя
    
.def temp = R16 ; регистр временного хранения  
.def temp_int = R17 ; временная переменная для использования в прерывании 
.def temp_sreg = R18 ;временная для SREG   


    
    .cseg
    .org 0
    
    ;векторы прерываний
    rjmp init; reset On
    rjmp int_int0; INT0
    reti; I/O pins off
    reti; Timer1 compA Off
    rjmp int_timer1; Timer1 overlow
    rjmp int_timer0; Timer0 overlow
    reti; EEPROM ready Off
    reti; Analog Comp Off
    reti; ADC conversion Off

     ;инициализация при первом запуске  
init:	

;    ldi temp, 0x67
;    out OSCCAL,temp       ; тактовая частота для протеуса
    
    
    sbi ACSR,ACD ;отключить компаратор

;    ldi temp,0b10000000
;    out ACSR,temp;для мплаба, в протеусе работает верхняя строчка.
    
    ldi temp,(1<<PUD|1<<ISC01|1<<ISC00)
    out MCUCR,temp ; настройка прерывания INT0 по фронту, отключение подтягивающих резисторов
    
    ldi temp,(1<<INT0)	;настройка прерываний
    out gimsk,temp ; разрешить внешнее прерывание по INT0

    ldi temp,( 1<<TOIE1|1<<TOIE0)
    out timsk,temp ; разрешить прерывания при переполнении таймеров TMR0 и TMR1
    
    ldi temp,0b00011000 ;настройка порта 
    out ddrb,temp;PB3,PB4 на выход
    
 
    ldi mode,3; запись режима лампа + вентилятор
        

    
    ;_____включили выключатель, запускаем систему, согласно режима работы ________
on:
    ;выдержка таймера устанавливается в зависимости от режима

    clr temp
    out tcnt1,temp; обнуление таймеров
    out tcnt0,temp
    
    ldi ms_delay,1 ; 164мс
    
;    ldi delay,255; 5,12 сек*255 = 22мин
    ldi delay,2; для проверки,основной режим работы 10 сек.
    
;    sbrc mode,lamp_mode; если включено освещение включаем 1 час выдежки
;    ldi delay_H,2; 22мин*3 = 64мин.(2-1-0 3 такта)
    ;для проверки, в основной версии коменты убрать
    ;__________________________________________________________________________________
    
    ldi temp,(1<<CS02|1<<CS01) ; установил по спаду |1<<CS00)
    out tccr0,temp ;запуск таймера с внешним входом по спаду; фронту
    sei ; разрешаем прерывания
    
    on_wait: ;ожидаем наличия сетевого напряжения
    sbrs flags,power
    rjmp on_wait
    
;    ldi temp,(1<<PSR1)
;    out SFIOR,temp ; сброс прескаллера
    
    ldi temp,(1<<CS13|1<<CS12|1<<CS11|1<<CS10)
    out tccr1,temp ;запуск таймера TMR1 с предделителем СК/1024 переполнение через 164 мс   


    sbrc mode,lamp_mode
    sbi PORTB,out_lamp
    sbrc mode,vent_mode
    sbi PORTB,out_vent ; запуск вентилятора и лампы согласно режима работы
    sbrc mode,vent_mode
    sbr flags,(1<<vent)
    
stopwait:  
    tst delay_H ;проверка срабатывания таймера общей выдержки
    brne off_on_en
    tst delay 
    breq stopall
    
off_on_en:
    tst ms_delay ;проверка срабатывания выключателя
    breq off_on
    rjmp stopwait

    ;========обработка включения/выключения выключателя===========    
off_on: 	
    cli ; запретить прерывания
    cbi PORTB,out_vent; выключаем все
    cbr flags,(1<<vent)
    cbi PORTB,out_lamp
    
    clr delay_H; очистка переменной для исключения прибавления ко времени выдержки при включенном вентиляторе
    
    clr temp
    out tccr0,temp
    out tccr1,temp ; стоп таймеры
    
    cbr flags,(1<<power)
     
    dec mode ;переключение режима от большего числа к меньшему
    tst mode
    brne on
    ldi mode,3;кольцевание режима 3-2-1-3 и т.д.
    
    rjmp on
;===========================================================================


    
    
 
;__________________ После отработки таймера выдержки___________________________    
    
stopall:
    cbi PORTB,out_lamp; выключаем освещение
    sbrc mode,vent_mode; если вентилятор был включен - выключаем на 22 мин.
    rjmp vent_off
    
;__________________ждем выключения-включения выключателя ______________________

stop_1: ;отработка включения/выключения выключателя
    tst ms_delay
    brne stop_2
    rjmp off_on

 
stop_2:; выключатель не выключался
    ; вентилятор включить на 1 мин каждые 22 мин.
    tst delay ;проверка таймера 
    brne stop_1
    sbrc flags,vent
    rjmp vent_off
    sbi PORTB,out_vent;включение вентилятора
    sbr flags,(1<<vent); установка флага включеного вентилятора
    
    ldi delay,1 ; для проверки. время работы вентилятора 5 сек.
;    ldi delay,12; установка выдержки 1 мин
    
    rjmp stop_1
    
vent_off:;выключение вентилятора на 22 мин.   
    cbi PORTB,out_vent
    cbr flags,(1<<vent);сброс флага включеного вентилятора
    
    ldi delay,1 ;для проверки, время паузы вентилятора 5 сек
;    ldi delay,255; установка выдержки 22 мин.
    
    rjmp stop_1
;______________________________________________________________________________    
     
;+++++++ Обработка прерываний +++++++++++++++++++++++++++++++  
int_int0:  
    ;каждый фронт импульса сети сбрасывает счетчик задержки выключателя
    in temp_sreg,SREG
    
    clr temp_int
    out tcnt1,temp_int
    ldi ms_delay,1
    

    sbr flags,(1<<power)
    
    out SREG,temp_sreg
    reti
    
int_timer0: ;счет таймера переполненй каждые 5,12 сек
    in temp_sreg,SREG
    
    subi delay,1
    sbci delay_H,0
    
    out SREG,temp_sreg
    reti

int_timer1: ;счет таймера переполнений 164 мС
    in temp_sreg,SREG
    
    dec ms_delay
    
    out SREG,temp_sreg
    reti
    
    



