;*********************************************************************************************
; Ch-DULED-10.asm					 *
; Ch-DULED-15.asm					 * 10 версия с функцией сохранения параметров по кнопки вкл/выкл
;*********************************************************************************************

	list      p=12F683        ; list directive to define processor
	#include <p12F683.inc>    ; processor specific variable definitions
	errorlevel  -302          ; suppress message 302 from list file
	__CONFIG   _FCMEN_ON & _IESO_OFF & _CP_ON & _CPD_ON & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT 
;========================================
#define		IFNZ		btfss	STATUS,Z
#define		IFZ			btfsc	STATUS,Z
#define		BANK0		bcf		STATUS,RP0
#define		BANK1		bsf		STATUS,RP0
;========================================
#define		PWM1		b_GPIO,4		; 
#define		PWM2		b_GPIO,0		; 
#define		PWM3		b_GPIO,1		; 
#define		LED1		b_GPIO,5		; 
#define		IRDA_DU		GPIO,2			; 
;========================================
#define 	BeginPWM 	flag_0,0		; бит запуска изменение яркости
#define 	CR		 	flag_0,1		; цикл горения красных светодиодов
#define 	CB		 	flag_0,2		; цикл горения синих светодиодов
#define 	CG		 	flag_0,3		; цикл горения зеленых светодиодов
#define 	E_data		flag_0,4		; 

#define 	ON_OFF 		flag_01,1		; включение освещения
#define 	WHR 		flag_01,2		; цикл горения и цвет белый
#define 	AR		 	flag_01,3		; альфа режим
#define 	BR		 	flag_01,4		; бетта режим
#define 	GR		 	flag_01,5		; гамма режим
#define 	DN		 	flag_01,6		; динамика

;========================================
;bank 0
#define		BITZ_N		flag_12,1		; бит начала байта
#define		BITZ_P		flag_12,2		; бит конца байта
#define		S0			flag_12,3		; бит начала сканирования посылки
#define		S1			flag_12,4		; 
#define		S2			flag_12,5		; 
#define		S3			flag_12,6		; 

;bank 1
#define		KD			flag_13,0		; контроль ожидания синхроимпульса
#define		PBP			flag_13,1		; бит контроля повторного прерывания по большому периоду
#define		P_M_B		flag_13,2		; бит типа текущего периода 0 малый 1-большой
#define		KO			flag_13,3		; 
#define		KMPER		flag_13,4		; контроль малого периода
#define		KBPER		flag_13,5		; контроль большого периода
;========================================
#define		KOD_YES		flag_1,5		; бит данные готовы
#define		pspn		flag_1,6		; бит смены нажатия клавиши
#define		ISOP		flag_1,7		; бит индикации состояния пароля
;========================================
#define 	TABLESIZE   .128			; 
#define 	RAZRD		.126			; 
#define		DAN			.20				; функция залипания клавиши для автонабора.13 от .10
#define		SPUAN		.150				; значение скорости автонабора по умолчанию 18
;========================================
; описание портов клавиатуры
#define		VL_UP		flag_11,0		; клавиша функция слево			16
#define		VL_DN		flag_11,1		; клавиша функция справо		17
#define		CH_UP		flag_11,2		; клавиша параметр больше		32
#define		CH_DN		flag_11,3		; клавиша параметр меньше		33
#define		KL_PF		flag_11,4		; клавиша функция				38
#define		KL_TV		flag_11,5		; клавиша ручного управления	12
#define		KL_EX		flag_11,6		; клавиша быстрый выход			13
;========================================
#define		kl_no	flag_3,0			; бит удержания клавиши
;========================================
	cblock	0x020

;========================================
flag_0									; флаги управления
flag_01									;
PhaseH									;
Yrkost_BLUE								; Holds duty cycle for PWM channel 0 
Yrkost_RED	 							; Holds duty cycle for PWM channel 1
Yrkost_GREEN							; Holds duty cycle for PWM channel 2
skorost									; скорость изменния.
end_stek								;*
;========================================
Phase_BLUE								; 
Phase_RED								; 
Phase_GREEN								; 
PhaseL									; PhaseL и PhaseH проводят синусоидальное местоположение указателя
IntCount								;
;========================================
Temp									;
b_GPIO									; буфер порта
flag_3									; 
flag_11									; 
uskor									; 
uskor_1									;
 
timer_led								; таймер светодиода индикации приема ик-сигнала
b_zad_ind
;========================================
flag_1									; 
flag_12									; 
flag_13                    				; 
synh_bayt								; синхро байт
data_bayt,data_baytp					; байт данных
klav_naj								; переменная формирования длительности нажатия клавиши
chetch_polbit							; счетсик загружаемых полу байт
reg_ik									; приемный порт ИК порта
;========================================
;================================
adr_e									; переменные для работы с EEPROM
data_e									; 
chtteep								    ; счетчик программы работы с EEPROM
perem1							; 
perem2							; 
;================================
ti_sohr							; таймер автосохранения данных
;================================
	endc
	cblock	0x70
w_temp					; variable used for context saving
status_temp				; variable used for context saving
pclath_temp				; variable used for context saving

	endc


;******************************************************************************
;
; Код начинает выполняться отсюда 	
; Это будет помещенный компоновщиком в местоположении памяти bet'n 0 и 4

;STARTUP	CODE 0x0000	
			ORG     0x000             	; processor reset vector
  	goto	Main

	nop
	nop
	nop
;============================================================================================
Interrupt 			;Interrupt Vector
			ORG     0x004             	; interrupt vector location
			movwf	w_temp				; save off current W register contents
			movf	STATUS,w			; move status register into W register
			movwf	status_temp			; save off contents of STATUS register
			
			call	preryvanie			; 
;ISR RestoreData
			movf	status_temp,w		;отыщите копию регистра STATUS
			movwf	STATUS				;восстановите pre-isr содержание регистра STATUS
			swapf	w_temp,f			; 
			swapf	w_temp,w			; restore pre-isr W register contents
		  retfie						; return from interrupt
;============================================================================================
;============================================================================================
		
		; Это - 128 таблиц входа, содержащих 1 цикл волны синуса.
		; 7-битовое значение индекса таблицы требуется.
SineTable
			andlw	TABLESIZE-1			;Маскируйте недопустимые входы
			movwf	Temp
			movlw	high (TableStart)	;получите верхние биты адреса для начала таблицы
			movwf	PCLATH
			movlw	low (TableStart)	;нагрузьте ниже биты адреса таблицы
			addwf	Temp,w				;добавьте смещение.
			btfsc	STATUS,C			;это переполнялось?
			incf	PCLATH,f			;yes:increment PCLATH
			movwf	PCL					;perform a complete jump
		
TableStart
		
		; 127 step
			retlw	.63			;1
			retlw	.66			;2
			retlw	.69			;3
			retlw	.72			;4
			retlw	.75			;5
			retlw	.79			;6
			retlw	.82			;7
			retlw	.85			;8
			retlw	.87			;9
			retlw	.90			;10
			retlw	.93			;11
			retlw	.96			;12
			retlw	.99			;13
			retlw	.101			;14
			retlw	.104			;15
			retlw	.106			;16
			retlw	.108			;17
			retlw	.110			;18
			retlw	.112			;19
			retlw	.114			;20
			retlw	.116			;21
			retlw	.118			;22
			retlw	.119			;23
			retlw	.121			;24
			retlw	.122			;25
			retlw	.123			;26
			retlw	.124			;27
			retlw	.125			;28
			retlw	.125			;29
			retlw	.126			;30
			retlw	.126			;31
			retlw	.126			;32
			retlw	.126			;33
			retlw	.126			;34
			retlw	.126			;35
			retlw	.126			;36
			retlw	.125			;37
			retlw	.124			;38
			retlw	.123			;39
			retlw	.122			;40
			retlw	.121			;41
			retlw	.120			;42
			retlw	.119			;43
			retlw	.117			;44
			retlw	.115			;45
			retlw	.113			;46
			retlw	.111			;47
			retlw	.109			;48
			retlw	.107			;49
			retlw	.105			;50
			retlw	.102			;51
			retlw	.100			;52
			retlw	.97			;53
			retlw	.95			;54
			retlw	.92			;55
			retlw	.89			;56
			retlw	.86			;57
			retlw	.83			;58
			retlw	.80			;59
			retlw	.77			;60
			retlw	.74			;61
			retlw	.71			;62
			retlw	.68			;63
			retlw	.65			;64
			retlw	.61			;65
		;---------------------------------
			retlw	.58			;66
			retlw	.55			;67
			retlw	.52			;68
			retlw	.49			;69
			retlw	.46			;70
			retlw	.43			;71
			retlw	.40			;72
			retlw	.37			;73
			retlw	.34			;74
			retlw	.31			;75
			retlw	.29			;76
			retlw	.26			;77
			retlw	.24			;78
			retlw	.21			;79
			retlw	.19			;80
			retlw	.17			;81
			retlw	.15			;82
			retlw	.13			;83
			retlw	.11			;84
			retlw	.09			;85
			retlw	.07			;86
			retlw	.06			;87
			retlw	.05			;88
			retlw	.04			;89
			retlw	.03			;90
			retlw	.02			;91
		;---------------------------------
			retlw	.01			;92
			retlw	.00			;93
			retlw	.00			;94
			retlw	.00			;95
			retlw	.00			;96
			retlw	.00			;97
			retlw	.00			;98
			retlw	.00			;99
			retlw	.01			;100
			retlw	.01			;101
		;---------------------------------
			retlw	.02			;102
			retlw	.03			;103
			retlw	.04			;104
			retlw	.05			;105
			retlw	.07			;106
			retlw	.08			;107
			retlw	.10			;108
			retlw	.12			;109
			retlw	.14			;110
			retlw	.16			;111
			retlw	.18			;112
			retlw	.20			;113
			retlw	.22			;114
			retlw	.25			;115
			retlw	.27			;116
			retlw	.30			;117
			retlw	.33			;118
			retlw	.36			;119
			retlw	.39			;120
			retlw	.41			;121
			retlw	.44			;122
			retlw	.47			;123
			retlw	.51			;124
			retlw	.54			;125
			retlw	.57			;126
			retlw	.60			;127
			retlw	.63			;128
;============================================================================================


;Главный раздел кода начинает выполняться отсюда
;============================================================================================
Main
;			call    0x3FF             	; калибровка внутреннего генератора (34E4) 
			bsf     STATUS,RP0        	; set file register bank to 1 
			movlw	b'01110001'			; частота 8 мГц, внутренний генератор
			movwf   OSCCON            	; update register with factory cal value 
			movlw	b'00000000'			; подстройка частоты +/-0 
			movwf   OSCTUNE				;
;======================================== настройка АЦП
			clrf	ANSEL 				; все входы цифровые
;======================================== 
			bcf     STATUS,RP0        	; set file register bank to 0
;======================================== 
			movlw	0x07	 			; отключение компараторов
			movwf	CMCON0	 			;
;======================================== настройка порта
			clrf	GPIO	 			;
			bsf		STATUS,RP0	 		; выбрать банк 1			
			movlw 	b'00000100' 		; настройка порта
			movwf	TRISIO 				;
;======================================== 
			movlw 	b'00001111' 		; перывание по заднему фронту
			movwf	OPTION_REG			; предделитель подключен к сторожевому таймеру
;======================================== 
			movlw 	b'00000000' 		; выключить подтягивающие резисторы GP2
			movwf	WPU 				;
			movlw	b'00000000'			; нет прерываний по входам
			movwf	IOC					;	 			
			bcf		STATUS,RP0	 		; выбрать банк 0
;======================================== 
		; настройка таймера	TMP1		; 
			bcf		STATUS,RP0			; выбрать банк 0
			movlw	b'00010001'			; таймер включен, предделитель 8/4 мг = 1:2 - 1 000 000 гц
			movwf	T1CON				;
;======================================== 
; очистка памяти данных
			movlw	0x20				; 
			movwf	FSR					; 
ClfMem		clrf	INDF				; 
			incf	FSR,f				; 
			movlw	0x60				;
			subwf	FSR,w				;
			BNZ 	ClfMem				;
;======================================== 
			call	vost_data				; востановление настроек
;======================================== 

	;Инициализация Прерываний
			movlw	b'11110000'			;Разрешите глобальный и прерывания от ТМР0 и INT0
			movwf	INTCON				;		
;============================================================================================
		;	bsf		LED1				; 
;;
;			bsf		CR					;		
;			bsf		AR					;		
;			movlw	.10						; 
;			movwf	skorost					; 		
;============================================================================================
; Главный цикл программы начинается здесь. Процесс сигнала PWM 
; поколение управляется прерываниями Timer0. Программный флажок
; названный 'BeginBWM' установлен в хранении и поиске информации Timer0 в начале 
; новый период PWM. Когда флажок обнаружен в основном цикл,
; измерительный потенциометр выбран, синусоидальный указатель увеличен,
; и новые значения цикла режима работы определены для трех сигналов PWM.
MainLoop

			;==============				;
		;	clrwdt						; сброс сторожевого таймера++++++
		;	movfw	uskor				;
		;	movwf	b_zad_ind			;
		;	movf	b_zad_ind,f			;	
		;	BNZ		$-3					;
	
			movfw	uskor				;
			movwf	b_zad_ind			;
			call	ind_zad				; 
	
			call	klava				; 

			;==============				;
		btfss	ON_OFF					; выключение
	goto	MainLoop					;
			;==============				;
		btfss	BeginPWM				; флаг разрешения изменения яркости  
		goto	MainLoop				; 
		bcf		BeginPWM				; сбросить бит разрешения изменения яркости
		
		btfsc	DN						; динамический статический режим
	goto	end_DN						; 
		decfsz	PhaseL,F				; уменьшить 
	goto	end_DN						; 
		
		incf	PhaseH,F				; текущая фаза	
		incf	Phase_BLUE,f			; 
		incf	Phase_RED,f				; 
		incf	Phase_GREEN,f			; 

		movfw	skorost					; задается скорость изменения огня
		movwf	PhaseL					; 
end_DN
;============================================================================================
			btfsc	AR					; альфа режим
		goto	cik_AR					; 
			btfsc	BR					; бета режим
		goto	cik_BR					; 
			btfsc	GR					; гамма режим
		goto	cik_GR					; 
			btfsc	WHR					; белый
		goto	cik_WHR					;
;============================================================================================
cik_WHR	; гамма режим
			movf	PhaseH,W			;	 
			andlw	0x7f				; преобразование к диапазону 0-127 	 						
			call	SineTable			;
			movwf	Yrkost_BLUE			;
			movwf	Yrkost_RED			;
			movwf	Yrkost_GREEN		;

		goto	MainLoop				;
;============================================================================================
cik_AR	; альфа режим
			btfss	CB				; если синий активный, проверить яркость = 0
		goto	$+.9				;
			movf	Yrkost_BLUE,f	; 
			btfss	STATUS,Z		;
		goto	$+.6				;
			bcf		CB				; если яркость =0 отключить синий и включить красный
			bsf		CR				;
			movlw	.101
			movwf	Phase_RED
		goto	end_pet

			btfss	CR				;		
		goto	$+.9				;
			movf	Yrkost_RED,f	;
			btfss	STATUS,Z		;
		goto	$+.6				;
			bcf		CR				; если яркость =0 отключить красный и включить зеленый
			bsf		CG				;
			movlw	.101			;
			movwf	Phase_GREEN		;
		goto	end_pet

			btfss	CG				;
		goto	end_pet				;
			movf	Yrkost_GREEN,f	;
			btfss	STATUS,Z		;
		goto	end_pet				;
			bcf		CG				; если яркость =0 отключить зеленый и включить синий
			bsf		CB				;
			movlw	.101			;
			movwf	Phase_BLUE		;
		goto	end_pet				;
;============================================================================================
cik_BR	; бета режим
			btfss	CB				; если синий активный, проверить яркость = 0
		goto	$+.12				;
			movf	Yrkost_BLUE,f	; 
			btfss	STATUS,Z		;
		goto	$+.9				;
			bcf		CB				; если яркость =0 отключить синий и включить красный
			bsf		CR				;
			movlw	.101			;
			movwf	Phase_RED		;
			bsf		CG				;
			movlw	.32				;
			movwf	Phase_GREEN		;
		goto	end_pet				;

			btfss	CR				;		
		goto	$+.12				;
			movf	Yrkost_RED,f	;
			btfss	STATUS,Z		;
		goto	$+.9				;
			bcf		CR				; если яркость =0 отключить синий и включить красный
			bsf		CG				;
			movlw	.101			;
			movwf	Phase_GREEN		;
			bsf		CB				;
			movlw	.32				;
			movwf	Phase_BLUE		;
		goto	end_pet				;

			btfss	CG				;
		goto	end_pet				;
			movf	Yrkost_GREEN,f	;
			btfss	STATUS,Z		;
		goto	end_pet				;
			bcf		CG				; если яркость =0 отключить синий и включить красный
			bsf		CB				;
			movlw	.101			;
			movwf	Phase_BLUE		;
			bsf		CR				;
			movlw	.32				;
			movwf	Phase_RED		;
;		goto	end_pet
;=====================================
end_pet		; управление яркостью каналов
			btfss	CB				; 		
		goto	$+.5				;			
			movf	Phase_BLUE,W	;	 
			andlw	0x7f			; преобразование к диапазону 0-127 	 						
			call	SineTable		;
			movwf	Yrkost_BLUE		;

			btfss	CR				; 		
		goto	$+.5				;
			movf	Phase_RED,W		;	 
			andlw	0x7f			; преобразование к диапазону 0-127 		
			call 	SineTable		;
			movwf	Yrkost_RED		;

			btfss	CG				; 		
	goto	MainLoop				;
			movf	Phase_GREEN,W	;		 
			andlw	0x7f			; преобразование к диапазону 0-127 	
			call 	SineTable		;
			movwf	Yrkost_GREEN	;
	goto	MainLoop				;
;============================================================================================
cik_GR	; гамма режим
			movf	PhaseH,W		;	 
			andlw	0x7f			; преобразование к диапазону 0-127 	 						
			call	SineTable		;
			movwf	Yrkost_BLUE		;

			movf	PhaseH,W		;	 
			addlw	.42				; Phase2 = Phase1 + 0x55 для первого сдвига фазы 120 градусов
			andlw	0x7f			; преобразование к диапазону 0-127 		
			call 	SineTable		;
			movwf	Yrkost_RED		;

			movf	PhaseH,W		;		 
			addlw	.85				; Phase3 = Phase1 + 0xAA для второго сдвига фазы 240 градусов		
			andlw	0x7f			; преобразование к диапазону 0-127 	
			call 	SineTable		;
			movwf	Yrkost_GREEN	;
		goto	MainLoop			;
;============================================================================================
;============================================================================================
;============================================================================================






;============================================================================================
;============================================================================================
;==================== цикл индикации ========================================================
ind_zad									; задежка вывода индикации
			clrwdt						; сброс сторожевого таймера++++++
			movf	b_zad_ind,f			;	
			BNZ		$-3					;
		return							; 
;============================================================================================
;============================================================================================
preryvanie								;
			btfss  	INTCON,T0IF			;
		goto	end_TMP0
			btfsc	ON_OFF				; выключение
		goto	$+.5					;
			bcf		PWM1				; Выключить канал
			bcf		PWM2				; Выключить канал
			bcf		PWM3				; Выключить канал			
		goto		restime	
			decfsz	IntCount,F			;если счетчик равен нулю рестарт свечения каналов
		goto	on_channel				;
			movlw	RAZRD+1				; инициализировать счетчик IntCount = RAZRD + 1
			movwf	IntCount			; 
			bsf		BeginPWM			; Флажок установити для главного программного цикла (изменение яркости)
;========================================
on_channel
			movf	Yrkost_BLUE,W		; 
			subwf	IntCount,W			; 
			btfss	STATUS,C			; совпадение заданной яркости канала и счетчика чркости
		goto	$+.3					; 
			bcf		PWM1				; Включить канал
		goto	$+.2					;
			bsf		PWM1				; Включить канал		
			
			movf	Yrkost_RED,W		; 
			subwf	IntCount,W			; 
			btfss	STATUS,C			; совпадение заданной яркости канала и счетчика чркости
		goto	$+.3					; 
			bcf		PWM2				; Включить канал
		goto	$+.2					;
			bsf		PWM2				; Включить канал	

			movf	Yrkost_GREEN,W		; 
			subwf	IntCount,W			; 
			btfss	STATUS,C			; совпадение заданной яркости канала и счетчика чркости
		goto	$+.3					; 
			bcf		PWM3				; Включить канал
		goto	$+.2					;
			bsf		PWM3				; Включить канал
;============================================
restime
			movfw	b_GPIO				; переключение фаз на выходе порта
			movwf	GPIO				; одновременное
;============================================
			bcf  	INTCON,T0IF			;сбросить прерывание от таймера
;============================================	
			movlw	.150				; инициализировать таймер на длительность 150 тактов
			movwf	TMR0				;
;============================================
			btfsc	LED1
			goto	end_TMP0
			decfsz	timer_led,f
		goto	end_TMP0
			bsf		LED1
			movlw	.50
			movwf	timer_led
end_TMP0
;==============	программа формирования задежки индикации символов
			movf	b_zad_ind,f			; проверить время задежки вышло
			BZ		$+2					;
			decf	b_zad_ind,f			; 
;========================================================================== 
;			movf	ti_sohr,f			; 
;			btfsc	STATUS,Z			; 
;		goto	end_sohr				; 
;			decfsz	ti_sohr,f			; 	
;		goto	end_sohr				; 
;			call	zap_eeprom			; записать в память заводские установки 
;end_sohr
;========================================================================== 
; Дистанционное управление
;============================================== программа обработки прерываний от 		
			bcf		STATUS,RP0			; выбор банка 0	
			; прерывание от порта всегда разрешено		
			btfss	INTCON,INTE			; проверка прерывания по INT0I разрешено?
		return							; если прерывания запрещены ИК порт отключен !!!
			btfss	INTCON,INTF			; тестироваит прерывание от порта ввода вывода (от синхронизации сети)
		goto	pr_ccp					; если нет то прерывание от таймера
			bcf		INTCON,INTF			; если да, то сбросить флаг прерывания
;======================================== определение длительности периода тактирования сигнала
			bsf		STATUS,RP0			; выбор банка 1
			btfsc	OPTION_REG,INTEDG	; изменение полярности прерывания
		goto	$+.3					; 
			bsf		OPTION_REG,INTEDG	; по переднему
		goto	$+.2					; 
			bcf		OPTION_REG,INTEDG	; по заднему
;======================================== 
	; контроль прерыванйи по входу INT во время работы модуля ССР т.е. формирование малого и большого периода
	; дедектирования уровня сигнала
			bcf		STATUS,RP0			; выбор банка 0	
			btfss	S2					; контроль старт бита выполнен ( только после этого можно включать
		goto	stpp					; контроль периодов)
			btfss	KMPER				; контроль малого периода
		goto	conbp					; в момент большого это нормально
		goto	error_ir				; в момент малого периода это ОШИБКА
conbp		btfss	KBPER				;
		goto	stpp					;
			btfsc	PBP					; если приходит второе прерывание по входу INT0
		goto	error_ir				; в момент большого это ОШИБКА			
			bsf		PBP					; прерывание большого периода выполнено
		return							;
;======================================== ; контроль старт бита
stpp		btfsc	S3					; это начала посылки? 0 - начало передачи пакета
		goto	zagmd					;
			bsf		S3					; да это начало
			movlw	.28					; инициализировать счетчик полубит
			movwf	chetch_polbit		;
			clrf	reg_ik				; очистить сдвиговый регистра
;======================================== 
zagmd		; загрузка малой длительности		
			bcf		PBP					; инициализировать бит контроля прерывания ИНТ в момет большого периода	
			bcf		KD					; отключить контроль ожидания синхроимпульса	
			bsf		KMPER				; контроль малого периода включить		
			movlw	0x01				; загрузка 1/4 периода сигнала (тактовая 4 мГц)			
			movwf	CCPR1H				;
			movlw	0xA4				; 0xA4
			movwf	CCPR1L				;
			clrf	TMR1L				; очистить TMR1
			clrf	TMR1H				; синхронизировать таймер			
			movlw	b'00001011'			; включить модуль ССР1						
			movwf	CCP1CON				; 
			bsf		STATUS,RP0			; выбор банка 1
			bsf		PIE1,CCP1IE			; разрещить прерывание от модуля ССP1			
			bcf		STATUS,RP0			; выбор банка 0				
			bcf		PIR1,CCP1IF			; сбросить прерывание
		return							; 			
;======================================== 
pr_ccp		; обработка прерываний от модуля ССР
			bsf		STATUS,RP0			; выбор банка 1
			btfss	PIE1,CCP1IE			; проверка прерывания по CCP1 разрешено?
	return								; 
			bcf		STATUS,RP0			; выбор банка 0
			btfss	PIR1,CCP1IF			; 
	return								; если нет то прерывание от таймера
			bcf		PIR1,CCP1IF			; если да, то сбросить флаг прерывания
;======================================== 
			btfsc	KD					; контроль длительности, ожидания синхроимпульса
		goto	error_ir				;			
			decfsz	chetch_polbit,f		;
		goto	$+.2					;	
		goto	conskan					;
;========================================			
			btfsc 	S2 					; бит контроля выполнения условия СТАРТА
		goto	ob_rbit					; условие старта выполнено
			btfsc 	S1 					; условие бита 2 старта выполенно			
		goto	ks2						;
			btfsc 	S0 					; условие бита 1 старта выполенно
		goto	ks1						;
ks0			btfsc 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
		goto	error_ir				;
			bsf		S0					;
		goto	ob_rbit					;
ks1			btfss 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
		goto	error_ir				;
			bsf		S1					;
		goto	ob_rbit					;
ks2			btfsc 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
		goto	error_ir				;
			bsf		S2					;
;========================================
ob_rbit		btfss	P_M_B				; выбор длительности контроля длительности 0-малая,1-большая
		goto	decodi_mal				; обработка уровня малого периода	
				; обработка уровня большого периода	
			bcf		P_M_B				; подготовка бита обоработки малого периода				
			movlw	0x06				; загрузка длительности ожидания синхроинмпульса			
			movwf	CCPR1H				; 0x03
			movlw	0x00				; 0x48			
			movwf	CCPR1L				;
;======================================== 			
			bsf		KD					; включить контроль длительности ожидания синхроимпульса
			bcf		PBP					; сбросить бит контроля повторного прерывания в момент большого периода
			bcf		KMPER				; контроль малого периода отключить	
			bcf		KBPER				; контроль большого периода	отключить		
;======================================== чтение состояния уровня по входу IRDA_DU первый полубайт
			btfss 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
			bcf 	BITZ_N 				; установить BITZ_N в "0" 
			btfsc 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
			bsf 	BITZ_N				; нет установить BITZ_N в "1" 
		return							;
;========================================		
decodi_mal				; обработка уровня малого периода									;
			bsf		P_M_B				; загрузка большого периода
			movlw	0x03				; загрузка 1/2периода сигнала (тактовая 4 мГц)			
			movwf	CCPR1H				; 0x03
			movlw	0x48				; 0x48			
			movwf	CCPR1L				;
			bcf		PBP					; сбросить бит контроля повторного прерывания в момент большого периода 			
			bcf		KMPER				; контроль малого периода отключить
			bsf		KBPER				; контроль большого периода
;======================================== пропустить сканирование первого полубита последовательности)
			movlw	.27					;
			subwf	chetch_polbit,w		; первый полубайт не обрабатывать
			btfsc	STATUS,Z			;
		return							;
;======================================== чтение состояния уровня по входу IRDA_DU второй полубайт
			btfss 	IRDA_DU 			; проверить уровень на линии PORTB,1			
			bcf 	BITZ_P 				; установить BITZ_N в "0" 
			btfsc 	IRDA_DU 			; проверить уровень на линии PORTB,1			
			bsf 	BITZ_P				; нет установить BITZ_N в "1" 
;======================================== декодирование полученного бита и запись его в регистр сбвига
			btfss 	BITZ_N				; 
		goto	con2					;
			btfsc 	BITZ_P				; 
		goto	error_ir				; ошибка бита		
			bsf 	STATUS,C 			; установить С в "1" 	
		goto	zagb					;
con2		btfss 	BITZ_P				; 
		goto	error_ir				; ошибка бита		
			bcf 	STATUS,C 			; установить С в "0" 
zagb		rlf 	reg_ik,f 			; сдвиг влево для записи в регистре reg_ik
;========================================
			movlw	.17					; определение окончания формирования байтов			
			subwf	chetch_polbit,w		;
			btfss	STATUS,Z			;
		goto	$+.5					;	
			movfw	reg_ik				; загрузить синхро байт			
			movwf	synh_bayt			; и очистить регистр сдвига
			clrf	reg_ik				;			
	return								; 
			movlw	.1					;			
			subwf	chetch_polbit,w		;
			btfss	STATUS,Z			;
	return								;	
			movfw	reg_ik				; загрузить байт данных
			movwf	data_bayt			; 
			clrf	reg_ik				;			
	return								; 
;========================================
conskan		; процедура окончания сканирования посылки
			btfss 	IRDA_DU 			; проверить уровень на линии IRDA_DU			
		goto	error_ir				; если наблюдается уровень 0 - ОШИБКА
			bsf		KOD_YES				; код "готов"
			movlw	DAN					; функция залипания клавиши
			movwf	klav_naj			; 
;========================================
;			btfsc	LED1				; индикатор приема IR-данных
;		goto	$+3						; 
;			bsf		LED1				; 
;		goto	$+2						; 
;			bcf		LED1				; 
;========================================
;		goto	endirda
error_ir	; метка окончания при ошибке приема данных		
;			bcf		KOD_YES				; код "не готов"
;			clrf	klav_naj			; 
;			clrf	data_bayt			; 
;			clrf	synh_bayt			
endirda
			bsf		STATUS,RP0			; выбор банка 1
			bcf		OPTION_REG,INTEDG	; по заднему
			bcf		PIE1,CCP1IE			; запретить прерывание от модуля ССP2
			bcf		STATUS,RP0			; выбор банка 0
			clrf	CCPR1H				;
			clrf	CCPR1L				;
			clrf	flag_12				; 			
			clrf	flag_13				;			
			clrf	reg_ik				;			
			clrf	CCP1CON				; выключить модуль CCP1
			clrf	chetch_polbit		;
		return							;
;============================================================================================

;============================================================================================
klava		; программа обработки нажатия клавиш
; декодирование кодов
			clrf	flag_11				; сброс кодов клавиш
			btfss	KOD_YES				; данные готовы
		goto	end_klava				; 

			movfw	data_bayt			; 
			movwf	data_baytp			;
;========================================
; контроль смены нажатия клавиши
			btfss 	synh_bayt,3			; проверить 3 бит синхробайта смены нажатия клавиш			
		goto	prv0					;
			btfss 	pspn				; бит предыдущего состояния бита 3			
		goto	nosos1					;			
		goto	eysos					;
prv0		btfsc 	pspn				;
		goto	nosos0					;
		goto	eysos					;
nosos1		bsf		pspn				;					
		goto	$+.2					;
nosos0		bcf		pspn				;			
;========================================
; повторное нажатие						
			bcf		kl_no				; сбросить бит нажатия клавиши			
			movlw	SPUAN				; инициализация автонабора
			movwf	uskor_1				; 
			movwf	uskor				;
		goto	end_klava
;========================================
eysos		; преобразование кодов в биты управления	
			movfw	data_baytp			;
			sublw 	.17					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		VL_UP				; клавиша температура выше	17
		goto	end_cod					;
	
			movfw	data_baytp			;
			sublw 	.16					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		VL_DN				; клавиша температура ниже	16	
		goto	end_cod					;
	
			movfw	data_baytp			;
			sublw 	.33					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		CH_DN				; клавиша режим	33
		goto	end_cod					;
	
			movfw	data_baytp			;
			sublw 	.32					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		CH_UP				; клавиша режим	32
		goto	end_cod					;
	
			movfw	data_baytp			;
			sublw 	.38					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		KL_PF				; клавиша переключения цветовых режимов
		goto	end_cod					;
	
			movfw	data_baytp			;
			sublw 	.13					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		KL_TV				; клавиша ручного управления 12
		goto	end_cod					;
			
			movfw	data_baytp			;
			sublw 	.12					;
			btfss	STATUS,Z			;
		goto	$+.3					;
			bsf		KL_EX				; клавиша on/off
		goto	end_cod					;
;		goto	end_klava				;		
;================================= возврат к заводским настройкам.!
			movfw	data_baytp			;
			sublw 	.81					; клавиша перезапуска контроллера 166
			btfss	STATUS,Z			;
		goto	$+.2					;
		;	call	zap_eeprom			; записать в память заводские установки 
		nop
		goto	end_klava				;	
;=================================
end_cod									;
		;	movlw	.255
		;	movwf	ti_sohr
			
			bcf		LED1				; включить светодиод
			decfsz	klav_naj,f			; отсчет таймера "залипания клавиш" для функции автонабора
		goto	$+.3					;
			bcf		KOD_YES				; код обработан программой декодирования
		goto	end_klava
;============================================================================================
;============================================================================================
			btfss	KL_PF				; клавиша переключения цветовых режимов 
		goto	t_KL_PF					; 
			btfsc	kl_no				; 
		goto	end_vyh1				;
			bsf		kl_no				; бит клавиша нажата
			;================
			btfss	AR					; 
		goto	$+.6					; 	
			bcf		AR					; 
			bsf		BR					; 
			bcf		GR					; 
			bcf		WHR					; 			
		goto	end_per					; 
			btfss	BR					; 
		goto	$+.6					; 	
			bcf		AR					; 
			bcf		BR					; 
			bsf		GR					; 
			bcf		WHR					;		
		goto	end_per					; 	
			btfss	GR					; 
		goto	$+.6					; 	
			bcf		AR					; 
			bcf		BR					; 
			bcf		GR					; 
			bsf		WHR					; 
		goto	end_per					; 
			btfss	WHR					; 
		goto	$+.5					; 	
			bsf		AR					; 
			bcf		BR					; 
			bcf		GR					; 
			bcf		WHR					;		
;		goto	end_per					; 
end_per		
		clrf	PhaseH					; текущая фаза	
		clrf	Phase_BLUE				; 
		clrf	Phase_RED				; 
		clrf	Phase_GREEN				; 
		clrf	Yrkost_BLUE				; Holds duty cycle for PWM channel 0 
		clrf	Yrkost_RED	 			; Holds duty cycle for PWM channel 1
		clrf	Yrkost_GREEN			; Holds duty cycle for PWM channel 2
	return								;		
;========================================
t_KL_PF		btfss	KL_TV				; клавиша переключения динамический/статический режим 
		goto	t_VL_UP					; 
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата
			;================
			btfsc	DN					;
			goto	$+.3				;
			bsf		DN					;
			goto	$+.2				;
			bcf		DN					;
	return								;	
;========================================
t_VL_UP		btfss	VL_UP				; клавиша изменение скорости динамического режима
		goto	t_VL_DN					; скорость медленне
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата
			;================
 			movlw	.30					;
 			subwf	skorost,w			;	
 			btfsc	STATUS,Z			;
	return								;
 			movlw	.1					;
 			addwf	skorost,f			;
	return								;	
;========================================
t_VL_DN		btfss	VL_DN				; клавиша изменение скорости динамического режима
		goto	t_CH_UP					; скорость больше
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата
			;================
 			movlw	.1					;
 			subwf	skorost,w			;	
 			btfsc	STATUS,Z			;
	return								;
 			movlw	.1					;
 			subwf	skorost,f			;
	return								;	
;========================================	
t_CH_UP		btfss	CH_UP				; клавиша ВКЛ/ОТКЛ регулятор
		goto	t_CH_DN					; 
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата
			;================
			btfss	AR					; альфа режим
		goto	regBR					; 
			btfss	CB					; 			
		goto	$+.9					; 
			bcf		CB					; 
			bsf		CR					;
			movfw	Phase_BLUE			; 			
			movwf	Phase_RED			; 
			movfw	Yrkost_BLUE			; 			
			movwf	Yrkost_RED			;
			clrf	Yrkost_BLUE			; 
	return								;
			btfss	CR					; 			
		goto	$+.9					; 
			bcf		CR					; 
			bsf		CG					;
			movfw	Phase_RED			; 			
			movwf	Phase_GREEN			; 
			movfw	Yrkost_RED			; 			
			movwf	Yrkost_GREEN		; 
			clrf	Yrkost_RED			; 
	return								;
			btfss	CG					; 			
		goto	$+.8					; 
			bcf		CG					; 
			bsf		CB					;
			movfw	Phase_GREEN			; 			
			movwf	Phase_BLUE			; 
			movfw	Yrkost_GREEN		; 			
			movwf	Yrkost_BLUE			; 
			clrf	Yrkost_GREEN		; 
	return								;
;=============
regBR
		movlw	.5
		addwf	PhaseH,F				; текущая фаза	
		addwf	Phase_BLUE,f			; 
		addwf	Phase_RED,f				; 
		addwf	Phase_GREEN,f			; 			

	return								;	
;========================================	
t_CH_DN		btfss	CH_DN				; клавиша меньше 
		goto	t_KL_EX					; 
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата			
			;================
		movlw	.5
		addwf	PhaseH,F				; текущая фаза	
		addwf	Phase_BLUE,f			; 
		addwf	Phase_RED,f				; 
		addwf	Phase_GREEN,f			;			

	return								;
	
;========================================		
t_KL_EX		btfss	KL_EX				; клавиша ВКЛ/ОТКЛ регулятор
		goto	end_klava				; 
			btfsc	kl_no				; 
		goto	end_vyh1				; 
			bsf		kl_no				; бит клавиша нажата
			;================			; 
			btfss	ON_OFF				; 
		goto	$+.4					; 
			bcf		ON_OFF				; 
			call	zap_eeprom			; записать в память заводские установки 
	return								; 
			bsf		ON_OFF				; 
			call	zap_eeprom			; записать в память заводские установки 
	return								; 
;========================================

;========================================
end_klava								;
			bcf		kl_no				; сбросить бит нажатия клавиши			
			movlw	SPUAN				; инициализация автонабора
			movwf	uskor_1				; 
			movwf	uskor				;
	return								;											
;========================================
end_vyh1
			movlw	.5					; 
			subwf	uskor_1,w			; проверка достижения переменной величины 1
			BZ		end_vyh2			;	
			decfsz	uskor,f				; 
	return								;
			decf	uskor_1,f			; 
			movf	uskor_1,w			; 
			movwf	uskor				; 
end_vyh2								;			
			bcf		kl_no				;				
	return								;	
;============================================================================================
;====================востановление данных====================================================
vost_data								; 
			movlw	(end_stek-flag_0)+1	; 
			movwf	chtteep				; 
			movlw	flag_0				; 
			movwf	FSR					;  загрузка начала блока данных
			clrf	adr_e				; 			
povch									; 
			call	prov_eep			; сосчитать данные с EEPROM
			movwf	INDF				; загрузить в ОЗУ и увеличить указатель
			incf	FSR,f				; 		
			incf	adr_e,f				; увеличить адрес EEPROM
			decfsz	chtteep,f			; уменьшить счетчик и проверить на ноль
			goto	povch				; повториь если не ноль
	return								; 
;=================================================================================================
prov_eep	call	rd_eeprom			; вызвать данные
			movf	data_e,w
			movwf	perem1				; 
			incf	adr_e,f				; адрес для EEPROM
			call	rd_eeprom			; вызвать данные (копия)
			movf	data_e,w			;
			subwf	perem1,w			; сравнить на равенство данных в EEPROM
			btfss	STATUS,Z			; 
			goto	$+3					; 
			movf	data_e,w			; данные равны
		return							; 
			btfss	STATUS,C			; 
			goto	$+3					; 
			movf	data_e,w			; 
			goto	$+2					; 
			movf	perem1,w			; 
			bsf		E_data				; ошибка в EEPROM
		return							; 
;=================================================================================================
rd_eeprom	movfw	adr_e				; загрузить значение адреса чтения
			bsf		STATUS,RP0			; выбор банка 1
			movwf	EEADR				; выставить нулевой адрес
			bsf		EECON1,RD			; начать чтение с  EEPROM
			movfw	EEDATA				; сосчитать данные
			bcf		STATUS,RP0			; выбор банка 0
			movwf	data_e				; сохранить в переменной
	return
;=================================================================================================
zap_eeprom								; запись в EEPROM
			movf	INTCON,w
			movwf	perem1				; сохранить значение регистра INTCON			
			bcf		INTCON,GIE			; запретить все прерывания			
			
			clrwdt						; сброс сторожевого таймера++++++
			movlw	(end_stek-flag_0)+1	;	; для записи используются данные с адреса Tzad_h1 по kol_oh_vv	
			movwf	chtteep				; 
			movlw	flag_0
			movwf	FSR					; загрузка начала блока данных
			clrf	adr_e				; 			
povch1		
			clrwdt						; сброс сторожевого таймера++++++
			movf	INDF,w				; загрузить в ОЗУ и увеличить указатель
			call	zap_2byt_eeprom		;
			incf	FSR,f
			incf	adr_e,f				; увеличить адрес EEPROM
			decfsz	chtteep,f				; уменьшить счетчик и проверить на ноль
			goto	povch1				; повториь если не ноль
			call 	stop_wr_e
			movf	perem1,w
			movwf	INTCON				; востановить значение регистра INTCON
	return								;
;============================================================================================
zap_2byt_eeprom							;
			movwf	data_e				;
			movwf	perem2				;
			call	wr_eeprom			;
			incf	adr_e,f				; сохранение данных в EEPROM 
			movf	perem2,w			;
			movwf	data_e				;
			call	wr_eeprom			;
	return								;
;===============запись байта в EEPROM========================================================				
wr_eeprom		
			bsf		STATUS,RP0			; выбор банка 1
			btfsc	EECON1,WR			; ожидания окончания сохранения данных в EEPROM
		goto	$-1						; 
			bsf		EECON1,WREN			; разрешить запись
			bcf		STATUS,RP0			; выбор банка 0
			movfw	adr_e				; загрузить адрес
			bsf		STATUS,RP0			; выбор банка 1
			movwf	EEADR				; установка адреса 1
			bcf		STATUS,RP0			; выбор банка 0
			movfw	data_e				; и вызов переменой состояния для сохранения
			bsf		STATUS,RP0			; выбор банка 1
			movwf	EEDATA				; в EEPROM
			movlw	0x55				; активация цикла записи в EEPROM
			movwf	EECON2				;
			movlw	0xAA				;
			movwf	EECON2				;
			bsf		EECON1,WR			; начать запись
			bcf		STATUS,RP0			; выбрать банк 0
	return								;
;===============запрет записи в EEPROM=======================================================
stop_wr_e								; 
			bsf		STATUS,RP0			; выбрать банк 1
			btfsc	EECON1,WR			; ожидания окончания сохранения данных в EEPROM
			goto	$-1					; 
			bcf		EECON1,WREN			; запретить запись			
			bcf		STATUS,RP0			; выбрать банк 0
	return								;
;============================================================================================

;============================================================================================			
				FILL(goto 0x00),0x800-$   ; заполнить все оставшееся место кодом
;============================================================================================
			ORG		0x2100						; 	
;============================================================================================
			DE		b'00000010',b'00000010'	;  flag_0				; флаги управления
			DE		b'00001000',b'00001000'	;  flag_01				;
			DE		.00,.00					;  PhaseH				;
			DE		.00,.00					;  Yrkost_BLUE			; Holds duty cycle for PWM channel 0 
			DE		.00,.00					;  Yrkost_RED	 		; Holds duty cycle for PWM channel 1
			DE		.00,.00					;  Yrkost_GREEN			; Holds duty cycle for PWM channel 2
			DE		.10,.10					;  skorost				; скорость изменния.
			DE		.00,.00					;  end_stek				;*

;============================================================================================	

;============================================================================================	
	END
