;**********************************************************************
;                                                                     *
;    Filename:	    reg1.asm                                          *
;    Date:          20.09.2004                                        *
;    File Version:  1.02                                              *
;                                                                     *
;    Author:        Alexey Petrushev                                  *
;    Company:                                                         *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files required:                                                  *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:  Регулятор мощности паяльника                             *
;	     с возможностью отключения и таймером                     *
;**********************************************************************


	list      p=16f628            
	#include <p16f628.inc>        
	
	__CONFIG _WDT_ON&_INTRC_OSC_NOCLKOUT&_PWRTE_ON&_CP_OFF&_MCLRE_OFF&_BODEN_ON&_LVP_OFF


			org H'2100' 	; Initialize EEPROM Data 
			de H'0'

		cblock 0x70			
			W_TEMP			;временная переменная для W
			STATUS_TEMP		;временная переменная для STATUS
			TMR0_SAVE		;переменная для хранения значения таймера,длительности периода
			FLAGS			;флаговый регистр
		endc

		cblock 0x20			;адрес начала регистров ОЗУ
			Seg_Out				;сохраняем зачение для индикации
			Seg_Cycle			;счетчик циклов индикации
			Seg_RRF				;сохраняем зачение для сдвига
			Work_Cycle			;счетчик рабочих циклов
			Work_Cycle_SET		;счетчик установленных активных рабочих циклов
			Key_0				;тактов удержания кнопки 0
			Key_1				;тактов удержания кнопки 1
			Key_0_1				;тактов удержания кнопок 0 и 1
			TEMP				;временная переменная для всякой всячины
			ALARM_TMR_0			;счетчик для аварийного таймера 0
			ALARM_TMR_1			;счетчик для аварийного таймера 1
			ALARM_TMR_2			;счетчик для аварийного таймера 2
		endc

		org 0x00
			GOTO MAIN

		org 0x04
			GOTO INTERRUPT                  
			GOTO MAIN					;идем к началу
		
MAIN		;настройка портов 
			CLRF	STATUS				; обнуляем регистр статуса и порты
			CLRF	PORTA	
			CLRF	PORTB		
			MOVLW   H'FF'				; гасим индикатор с общим анодом
   			MOVWF	PORTB			 
			
			BANKSEL TRISA				; банк 01
			MOVLW   B'11100011'			; RA2-RA4 на вывод
   			MOVWF	TRISA		 
			MOVLW   B'00000001'			; RB0 на ввод
   			MOVWF	TRISB			 
			BANKSEL PORTA				; банк 00	

			;настройка OPTION_REG 
			BANKSEL	OPTION_REG			; банк 01
			MOVLW   B'00000110'			; прерывание по заднему фронту, предделитель 128
      		MOVWF	OPTION_REG		 
			BANKSEL PORTA				; банк 00	

			; настройка модуля компаратора
			MOVLW	B'00000111'
			MOVWF	CMCON				; выключаем все

			; настройка обработки прерываний  
			MOVLW   B'10010000'			; разрешаем внешнее прерывание 
  	    	MOVWF	INTCON		 

			CLRF	FLAGS				;сбросим фалаговый регистр
			CLRF	Key_0				;сбросим счетчик кнопок
			CLRF	Key_1				;сбросим счетчик кнопок
			CLRF	Key_0_1				;сбросим счетчик кнопок

			CLRF	ALARM_TMR_0			;аварийный таймер 0
			CLRF	ALARM_TMR_1			;аварийный таймер 1
			CLRF	ALARM_TMR_2			;аварийный таймер 2
		
			;чтитаем сохраненную мощьность
			BANKSEL TRISA				; банк 01
			MOVLW   .0
			MOVWF	EEADR				;адрес
			BSF		EECON1, RD			;чтение
			MOVF	EEDATA, W			;W=EEDATA
			BANKSEL PORTA				; банк 00	
			MOVWF	Work_Cycle_SET


START		BTFSC	FLAGS, 6				;проверим устройство включено или нет ?
			GOTO 	OFF_Start
			
			BTFSS	FLAGS, 7				;проверка необходимости включения
			GOTO	$+3						;включать не надо
			MOVLW   B'11111111'				;импульс на триак
			MOVWF	PORTA
			CLRWDT

			MOVF	Work_Cycle_SET, W		;загрузим счетчик активных циклов
			CALL	NUM_CODE				;преобразование
			CALL	INDICATION				;индикация

			MOVLW   B'11100011'				
			MOVWF	PORTA

			MOVLW 	.6		
			MOVWF 	TEMP
			MOVF	Work_Cycle_SET, W		;загрузим счетчик активных циклов
			CALL	NUM_CODE				;преобразование
			CALL	INDICATION				;индикация
			DECFSZ 	TEMP,F
			GOTO 	$-.4
			GOTO	START

OFF_Start	CLRWDT
			;мигаем индикатором не включая нагрузку,режим отключения
			BTFSC	FLAGS, 5				;проверим включать ли индикатор
			GOTO	START
			MOVF	Work_Cycle_SET, W		;загрузим счетчик активных циклов
			CALL	NUM_CODE				;преобразование
			CALL	INDICATION				;индикация
			GOTO	START

	
;---------------------Подпрограмма обработки прерываний----------------------------------------- 
INTERRUPT	MOVWF   W_TEMP				; сохраняем W 
			SWAPF   STATUS, W
			CLRF 	STATUS
			MOVWF	STATUS_TEMP			; сохраняем  STATUS
		
			;обрабтка необходимости включения-выключения
			INCF	Work_Cycle, F		;прибавим счетчик рабочих циклов
			MOVLW	.16					;проверим на предельное значение
			SUBWF	Work_Cycle, W
			BTFSC	STATUS, C
			CLRF	Work_Cycle 

			BCF		FLAGS, 7			;сбросим флаг включения
			MOVF	Work_Cycle_SET, W	;сравним счетчик рабочих и установленных циклов
			ADDLW	.1					;+1
			SUBWF	Work_Cycle, W
			BTFSS	STATUS, C
			BSF		FLAGS, 7			;стаим флаг включения

			CALL	KEY_TEST			;подпрограмма обработки кнопок
			CALL	LD_Interval	
			

RESTORE		SWAPF  	STATUS_TEMP,W
			MOVWF   STATUS
			SWAPF   W_TEMP, F
			SWAPF   W_TEMP,W
			BCF 	INTCON, INTF			;сбрасываем флаг
			RETFIE           
;----------------------------------------------------------------------------------------------- 


;---------------------Подпрограмма	изменения флага LD------------------------------------------ 
LD_Interval
			INCF	ALARM_TMR_0, F			;увеличим установку
			MOVLW	.25						;проверим время
			SUBWF	ALARM_TMR_0, W		
			BTFSS	STATUS, C
			RETURN
			CLRF	ALARM_TMR_0
			MOVLW	B'00100000'	    		;Инвиртируем флаг включения индикатора
			XORWF	FLAGS, F

			INCF	ALARM_TMR_1, F			;увеличим установку
			MOVLW	.120					;проверим время  (1 минуту)
			SUBWF	ALARM_TMR_1, W		
			BTFSS	STATUS, C
			RETURN
			CLRF	ALARM_TMR_1

			INCF	ALARM_TMR_2, F			;увеличим установку
			MOVLW	.120					;проверим время  (2 часа)
			SUBWF	ALARM_TMR_2, W		
			BTFSS	STATUS, C
			RETURN
			CLRF	ALARM_TMR_2

			BSF		FLAGS, 6				;отключим устройство
			RETURN
;----------------------------------------------------------------------------------------------- 

;---------------------Подпрограмма опроса кнопок------------------------------------------------ 
KEY_TEST	
			;проверка одновременного нажатия кнопок
			COMF	PORTA, W			;загрузим с инверсией
			ANDLW	B'00000011'			;маскируем лишнее
			XORLW	B'00000011'			;проверим
			BTFSS	STATUS, Z
			GOTO	Start_0_TEST
			;нажаты обе кнопки	
			INCF	Key_0_1, F 			;увеличим установку
			MOVLW	.50					;проверим время удержания
			SUBWF	Key_0_1, W		
			BTFSS	STATUS, C
			RETURN
			MOVLW	B'01000000'			;Инвиртируем флаг включения
			XORWF	FLAGS, F
			CLRF	Key_0_1
			CLRF	ALARM_TMR_1			;сбросим аварийный таймер минут
			CLRF	ALARM_TMR_2			;сбросим аварийный таймер минут
			RETURN

Start_0_TEST
			CLRF	Key_0_1

			;опрос кнопки 0
			INCF	Key_0, F			;+1
			BTFSC	PORTA, 0			
			CLRF	Key_0
			MOVLW	.30					;проверим время удержания
			SUBWF	Key_0, W		
			BTFSS	STATUS, C
			GOTO	END_0_TEST
			CLRF	Key_0
			INCF	Work_Cycle_SET, F 	;увеличим установку
			
			MOVLW	.15					;проверим на предельное значение
			SUBWF	Work_Cycle_SET, W
			BTFSS	STATUS, C
			GOTO	SAVE_SET_0 
			MOVLW	.15
			MOVWF	Work_Cycle_SET		;установим предельное значение
			
			CLRF	ALARM_TMR_1			;сбросим аварийный таймер минут			
			CLRF	ALARM_TMR_2			;сбросим аварийный таймер минут
			
SAVE_SET_0	MOVF	Work_Cycle_SET, W	;запишем в EEPROM
			BANKSEL TRISA				; банк 01
			MOVWF	EEDATA				;данные
			MOVLW   .0
			MOVWF	EEADR				;адрес
			BSF		EECON1, WREN		;разрешим запись
			BCF		INTCON, GIE			;запретить прерывания
			MOVLW	H'55'
			MOVWF	EECON2
			MOVLW	H'AA'
			MOVWF	EECON2
			BSF		EECON1, WR			;запишем
			BANKSEL PORTA				; банк 00	


END_0_TEST	
			;опрос кнопки 1
			INCF	Key_1, F			;+1
			BTFSC	PORTA, 1			
			CLRF	Key_1
			MOVLW	.30					;проверим время удержания
			SUBWF	Key_1, W		
			BTFSS	STATUS, C
			GOTO	END_1_TEST
			CLRF	Key_1
			DECF	Work_Cycle_SET, F 	;уменьшим установку

			MOVF	Work_Cycle_SET, W	;проверим на минимальное значение
			XORLW	H'FF'
			BTFSC	STATUS, Z
			CLRF	Work_Cycle_SET

			CLRF	ALARM_TMR_1			;сбросим аварийный таймер минут
			CLRF	ALARM_TMR_2			;сбросим аварийный таймер минут
			
			MOVF	Work_Cycle_SET, W	;запишем в EEPROM
			BANKSEL TRISA				; банк 01
			MOVWF	EEDATA				;данные
			MOVLW   .0
			MOVWF	EEADR				;адрес
			BSF		EECON1, WREN		;разрешим запись
			BCF		INTCON, GIE			;запретить прерывания
			MOVLW	H'55'
			MOVWF	EECON2
			MOVLW	H'AA'
			MOVWF	EECON2
			BSF		EECON1, WR			;запишем
			BANKSEL PORTA				; банк 00	

END_1_TEST
			RETURN
;----------------------------------------------------------------------------------------------- 


;---------------------Подпрограмма индикации --------------------------------------------------- 
INDICATION				;индикация в зависимости от числа сегментов
			MOVWF	Seg_Out				;сохраняем зачение для индикации
			MOVWF	Seg_RRF				;сохраняем зачение для сдвига
			MOVLW	.8
			MOVWF	Seg_Cycle			;счетчик циклов индикации
Cycle_Ind	BTFSC	Seg_RRF,0
			GOTO	None_Ind
			MOVF 	Seg_Out, W
			MOVWF	PORTB
			NOP
			NOP
			MOVLW	B'11111111'			;отключаем индикацию
			MOVWF	PORTB
			GOTO	End_Ind
None_Ind	NOP
			NOP
			NOP
			NOP
			NOP
			NOP
End_Ind		RRF		Seg_RRF, F			;сдвигаем
			DECFSZ	Seg_Cycle, F
			GOTO	Cycle_Ind
			RETURN
;----------------------------------------------------------------------------------------------- 

;---------------------Подпрограмма преобразования в 7 сегментный код---------------------------- 
NUM_CODE	ANDLW	B'00001111'
			ADDWF	PCL,F				;активный уровень 0
			RETLW 	B'10000000'			;0
			RETLW	B'11110010'			;1
			RETLW	B'01001000'			;2
			RETLW	B'01100000'			;3
			RETLW	B'00110010'			;4
			RETLW	B'00100100'			;5
			RETLW	B'00000100'			;6
			RETLW	B'11110000'			;7
			RETLW	B'00000000'			;8
			RETLW	B'00100000'			;9
			RETLW	B'00010000'			;A
			RETLW	B'00000110'			;b
			RETLW	B'10001100'			;C
			RETLW	B'01000010'			;d
			RETLW	B'00001100'			;E
			RETLW	B'00011100'			;F
;----------------------------------------------------------------------------------------------- 


	END

