	LIST	p=16F628
	#include "P16F628.INC"

;        __CONFIG 3F61h  
        radix DEC
;
w       equ     0
f       equ     1

PauseCntA equ	21h
PauseCntB equ	22h
Povtor	equ	23h

LED1	equ	24h	; Яркость 1го светодиода (гирлядны)	; 
LED2	equ	25h	; Яркость 2го светодиода (гирлядны)	; 
LED3	equ	26h	; Яркость 3го светодиода (гирлядны)	; 
LED4	equ	27h	; Яркость 4го светодиода (гирлядны)	; 

ShimTmr	equ	30h	; Отсчет ШИМ таймера

IntW	equ	31h	; Сохранение значения контекста
IntStat	equ	32h	; на время обработки прерывания

ShimCon	equ	33h	; Настройки ШИМ


#define LED1pin	PORTB,7	; ножка 1го светодиoда
#define LED2pin	PORTB,6	; ножка 2го светодиoда
#define LED3pin	PORTB,5	; ножка 3го светодиoда
#define LED4pin	PORTB,4	; ножка 3го светодиoда

#define ZeroPin	PORTA,4	; Ножка детектора "нуля" sin

#define sin   ShimCon,0	; Флаг начала полупериода Sin

;=====================================================
;
; Початок програми. Ініцілізація
;
;=====================================================

        org 0
        goto start	; (Start)

;=====================================================
; Подпрограмма обработки прерывания
;=====================================================
	org	4h

	movwf	IntW	; Сохряняем содержимое регистра
			; w на время обработки прерывания
	movf	STATUS,0; Сохряняем содержимое регистра
	movwf	IntStat	; STATUS на время обработки прерывания
	bcf	STATUS,RP0	; Банк 0


	bcf	INTCON,T0IF
				; Регулировка яркостью светодиодов с помощью ШИМ

	bcf	LED1pin		; Выключить 1й светодиод
	bcf	LED2pin		; Выключить 2й светодиод
	bcf	LED3pin		; Выключить 3й светодиод
	bcf	LED4pin		; Выключить 3й светодиод
	
	comf	ShimTmr,1	; Инверсия значений

	movf    LED1,W		; Полный ШИМ цикл - 255 циклов.
	subwf   ShimTmr,W	; Если текущее значение ШИМ счетчика больше "яркости" (LED1)
	btfss   STATUS,C	; то выключаем светодиод
	bsf	LED1pin


;	btfss	ZeroPin		; Если напряжение отсуствует
;	goto	NoVoltage	; то не включаем светодиоды.
	btfss	sin		; Если в прошлый раз sin=0,
	clrf	ShimTmr		; то сбрасываем ШИМ-счетчик,
	bsf	sin		; и устнавливаем sin=1.


	movf    LED2,W	; 
	subwf   ShimTmr,W		; 
	btfss   STATUS,C	; 
	bsf	LED2pin

	movf    LED3,W	; 
	subwf   ShimTmr,W		; 
	btfss   STATUS,C	; 
	bsf	LED3pin

	movf    LED4,W	; 
	subwf   ShimTmr,W		; 
	btfss   STATUS,C	; 
	bsf	LED4pin

NoVoltage

	comf	ShimTmr,1	; Инверсия значений

				; Приплюсовать 
	movlw	6h
	addwf	ShimTmr,1

	btfss	ZeroPin		; Если напряжение в сети = 0
	bcf	sin		; то устнавливаем sin=0.

	btfsc	PORTA,1		; Проверки на нажатие кнопки 1
	clrf	Povtor		; Сбросить счетчик повторов
	btfsc	PORTA,2		
	clrf	PauseCntA	

	movf	IntStat,w	; Восстановление контекста
	movwf	STATUS	
	swapf	IntW,F		; Тут приходится хитрить, чтобы сохранить бит Z
	swapf	IntW,W		; (movf его может изменить, а swapf - нет)

	retfie


;=====================================================
; Основна програма
;=====================================================
start
;-------------------------------; Первичная подготовка
	bcf	STATUS,RP0	; Банк 0
	bcf	STATUS,RP1	; Банк 0
	clrf	INTCON		; Запрет всех прерываний

	clrf	ShimCon		; Сброс всех настроек ШИМ

;-------------------------------; Иницилизация модуля компараторов
	bcf	STATUS,RP0	; Банк 0
	clrf	PORTA		; Иницилизация порта А	
	movlw	B'00000111'	;
	movwf	CMCON		; Компараторы выключены
	bsf	STATUS,RP0	; Банк 1
	movlw	0FFh		; Порт А - все входы
	movwf	TRISA		;
	bcf	STATUS,RP0	; Банк 0

	bsf	STATUS,RP0	; Банк 1
	clrf	VRCON		; Источник опорного напряжение выключен
	bcf	PIE1,6		; Прерывание от компараторов выключенно.
	bcf	STATUS,RP0	; Банк 0


;-------------------------------; Подготовка портов ввода-вывода
			; Порт A Мы уже настроимли в модуле компараторов
			; Порт В 

	bsf	STATUS,RP0	; Банк 1
	movlw	b'00000000'	; все - выходы.
	movwf	TRISB		; 
	bcf	STATUS,RP0	; Банк 0

;-------------------------------; Иницилизация модуля TMR0
	bsf	STATUS,RP0	; Банк 1
	bcf	OPTION_REG,5	; TMR0 работает от внутреннего генератора
	bsf	INTCON,T0IE	; Разрешено прерывание при переполнении
	bsf	OPTION_REG,PSA	; Предделитель перед WDT
	bcf	STATUS,RP0	; Банк 0

	bcf	INTCON,T0IF


;	bsf	INTCON,PEIE	; Включаем прерывания
	bsf	INTCON,GIE




	bcf	STATUS,RP0	; Банк 0

	clrf	PORTB

;-------------------------------; Бегущие огни (резкий переход)
BegOgniRezk
	movlw	.30
	movwf	Povtor		; Повторить хх раз

BegOgniRezkPov

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED1		; 				
	call	PAUSE1s

	clrf	LED1
	movlw	0FFh		; 
	movwf	LED2		; 				
	call	PAUSE1s

	clrf	LED2
	movlw	0FFh		; 
	movwf	LED3		; 				
	call	PAUSE1s

	clrf	LED3
	movlw	0FFh		; 
	movwf	LED4		; 				
	call	PAUSE1s

	clrf	LED4

	decfsz	Povtor,1
	goto	BegOgniRezkPov

;-------------------------------; Бегущие огни (плавный переход)
BegOgniPlav

	movlw	0h		; Подготовка светодиодов
	movwf	LED1		; Ве выключенно
	movwf	LED2		;
	movwf	LED3		;

	movlw	.30
	movwf	Povtor		; Повторить хх раз


Zazyg
;	call	GIRLemul	; Эмуляция гирлянды		; Подготовка
	call	PAUSE01s	; Пауза 0,1 сек.			;
	call	PAUSE01s	; Пауза 0,1 сек.			;
	call	PAUSE01s	; Пауза 0,1 сек.			;
								;
	incfsz	LED1,1		; Плавно увеличиваю яркость	;
	goto	Zazyg		; до максимума			;

BegOgniPlavLED1
								;
	movlw	0FFh		; Включаю яркость на 100%	;
	movwf	LED1		; 				;

	call	PAUSE5s

BegOgniPlavLED12
;	call	GIRLemul	; Эмуляция гирлянды		; 1й светодиод плавно 
	call	PAUSE01s	; Пауза 0,1 сек.		; переходит в 2й
	call	PAUSE01s
								;
	decfsz	LED1,1		; Уменьшаю яркость первого 	;
	nop			; светодиода и увеличиваю 	;
	incfsz	LED2,1		; второго			;
	goto	BegOgniPlavLED12				;

	clrf	LED1						
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED2		; 				

	call	PAUSE5s

BegOgniPlavLED23
;	call	GIRLemul	; Эмуляция гирлянды		; 2й светодиод плавно 
	call	PAUSE01s	; Пауза 0,1 сек.		; переходит в 3й
	call	PAUSE01s
								;
	decfsz	LED2,1		; Уменьшаю яркость первого 	;
	nop			; светодиода и увеличиваю 	;
	incfsz	LED3,1		; второго			;
	goto	BegOgniPlavLED23				;

	clrf	LED2						
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED3		; 				

	call	PAUSE5s

BegOgniPlavLED34
;	call	GIRLemul	; Эмуляция гирлянды		; 3й светодиод плавно 
	call	PAUSE01s	; Пауза 0,1 сек.		; переходит в 4й
	call	PAUSE01s

	decfsz	LED3,1		; Уменьшаю яркость первого 
	nop			; светодиода и увеличиваю 
	incfsz	LED4,1		; второго
	goto	BegOgniPlavLED34

	clrf	LED3
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED4		; 				

	call	PAUSE5s

BegOgniPlavLED41
;	call	GIRLemul	; Эмуляция гирлянды		; 4й светодиод плавно 
	call	PAUSE01s	; Пауза 0,1 сек.		; переходит в 1й
	call	PAUSE01s

	decfsz	LED4,1		; Уменьшаю яркость первого 
	nop			; светодиода и увеличиваю 
	incfsz	LED1,1		; второго
	goto	BegOgniPlavLED41

	clrf	LED4
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED1		; 				

	decfsz	Povtor,1	; Зацикливаемся
	goto	BegOgniPlavLED1

	goto	BegOgniMedlPlav



;-------------------------------; Бегущие огни (плавный переход, медленные)
BegOgniMedlPlav

	movlw	0h		; Подготовка светодиодов
	movwf	LED1		; Вcе выключенно
	movwf	LED2		;
	movwf	LED3		;

	movlw	.7
	movwf	Povtor		; Повторить хх раз


ZazygMedl
;	call	GIRLemul	; Эмуляция гирлянды		; Подготовка
	call	PAUSE01s	; Пауза 0,5 сек.		;
								;
	incfsz	LED1,1		; Плавно увеличиваю яркость	;
	goto	ZazygMedl	; до максимума			;

BegOgniMedlPlavLED1
								;
	movlw	0FFh		; Включаю яркость на 100%	;
	movwf	LED1		; 				;

	call	PAUSE15s
	call	PAUSE15s

BegOgniMedlPlavLED12
;	call	GIRLemul	; Эмуляция гирлянды		; 1й светодиод плавно 
	call	PAUSE1s		; Пауза 0,5 сек.		; переходит в 2й
	call	PAUSE05s	; Пауза 0,5 сек.
								;
	decfsz	LED1,1		; Уменьшаю яркость первого 	;
	nop			; светодиода и увеличиваю 	;
	incfsz	LED2,1		; второго			;
	goto	BegOgniMedlPlavLED12				;

	clrf	LED1						
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED2		; 				

	call	PAUSE15s
	call	PAUSE15s

BegOgniMedlPlavLED23
;	call	GIRLemul	; Эмуляция гирлянды		; 2й светодиод плавно 
	call	PAUSE1s		; Пауза 0,5 сек.		; переходит в 3й
	call	PAUSE05s	; Пауза 0,5 сек.
								;
	decfsz	LED2,1		; Уменьшаю яркость первого 	;
	nop			; светодиода и увеличиваю 	;
	incfsz	LED3,1		; второго			;
	goto	BegOgniMedlPlavLED23				;

	clrf	LED2						
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED3		; 				

	call	PAUSE15s
	call	PAUSE15s

BegOgniMedlPlavLED34
;	call	GIRLemul	; Эмуляция гирлянды		; 3й светодиод плавно 
	call	PAUSE1s		; Пауза 0,5 сек.		; переходит в 4й
	call	PAUSE05s	; Пауза 0,5 сек.

	decfsz	LED3,1		; Уменьшаю яркость первого 
	nop			; светодиода и увеличиваю 
	incfsz	LED4,1		; второго
	goto	BegOgniMedlPlavLED34

	clrf	LED3
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED4		; 				

	call	PAUSE15s
	call	PAUSE15s

BegOgniMedlPlavLED41
;	call	GIRLemul	; Эмуляция гирлянды		; 4й светодиод плавно 
	call	PAUSE1s		; Пауза 0,5 сек.		; переходит в 1й
	call	PAUSE05s	; Пауза 0,5 сек.

	decfsz	LED4,1		; Уменьшаю яркость первого 
	nop			; светодиода и увеличиваю 
	incfsz	LED1,1		; второго
	goto	BegOgniMedlPlavLED41

	clrf	LED4
	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED1		; 				

	decfsz	Povtor,1	; Зацикливаемся
	goto	BegOgniMedlPlavLED1

	goto	BegOgniMedRezk



;-------------------------------; Бегущие огни (резкий переход, медленно)
BegOgniMedRezk
	movlw	.7
	movwf	Povtor		; Повторить хх раз

BegOgniMedRezkPov

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED1		; 				
	call	PAUSE15s
	call	PAUSE1s

	clrf	LED1
	movlw	0FFh		; 
	movwf	LED2		; 				
	call	PAUSE15s
	call	PAUSE1s

	clrf	LED2
	movlw	0FFh		; 
	movwf	LED3		; 				
	call	PAUSE15s
	call	PAUSE1s

	clrf	LED3
	movlw	0FFh		; 
	movwf	LED4		; 				
	call	PAUSE15s
	call	PAUSE1s

	clrf	LED4

	decfsz	Povtor,1
	goto	BegOgniMedRezkPov

	goto	BegTenRezk


;-------------------------------; Бегущая тень (резкий переход)
BegTenRezk
	movlw	.10
	movwf	Povtor		; Повторить хх раз

BegTenRezkPov

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED2		; 				
	movwf	LED3		; 				
	movwf	LED4		; 				
	movlw	.128
	movwf	LED1		
	call	PAUSE1s
	movlw	.64
	movwf	LED1		
	movlw	.32
	movwf	LED1		
	call	PAUSE1s
	clrf	LED1
	call	PAUSE5s

	movlw	0FFh		; 
	movwf	LED1		; 				
	movwf	LED3		; 				
	movwf	LED4		; 				
	movlw	.128
	movwf	LED2		
	call	PAUSE1s
	movlw	.64
	movwf	LED2		
	movlw	.32
	movwf	LED2		
	call	PAUSE1s
	clrf	LED2

	call	PAUSE5s

	movlw	0FFh		; 
	movwf	LED1		; 				
	movwf	LED2		; 				
	movwf	LED4		; 				
	movlw	.128
	movwf	LED3		
	call	PAUSE1s
	movlw	.64
	movwf	LED3		
	movlw	.32
	movwf	LED3		
	call	PAUSE1s
	clrf	LED3
	call	PAUSE5s

	movlw	0FFh		; 
	movwf	LED1		; 				
	movwf	LED2		; 				
	movwf	LED3		; 				
	movlw	.128
	movwf	LED4		
	call	PAUSE1s
	movlw	.64
	movwf	LED4		
	movlw	.32
	movwf	LED4		
	call	PAUSE1s
	clrf	LED4
	call	PAUSE5s

	decfsz	Povtor,1
	goto	BegTenRezkPov

;	goto	BegOgniRezk




;-------------------------------; Столбик
Stolb

	movlw	0h		; Подготовка светодиодов
	movwf	LED1		; Ве выключенно
	movwf	LED2		;
	movwf	LED3		;

	movlw	.10
	movwf	Povtor		; Повторить хх раз


StolbLED1on
	call	PAUSE05s	; Пауза 0,5 сек.		
								;
	incfsz	LED1,1		;
	goto	StolbLED1on

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED1		; 				

	call	PAUSE5s

StolbLED2on
	call	PAUSE05s	; Пауза 0,5 сек.		
								;
	incfsz	LED2,1		;
	goto	StolbLED2on

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED2		; 				

	call	PAUSE5s

StolbLED3on
	call	PAUSE05s	; Пауза 0,5 сек.

	incfsz	LED3,1		;
	goto	StolbLED3on

	movlw	0FFh		; Включаю яркость на 100%	
	movwf	LED3		; 				

	call	PAUSE5s

StolbLED4on
	call	PAUSE05s	; Пауза 0,5 сек.

	incfsz	LED4,1		;
	goto	StolbLED4on

	movlw	0FFh		; 
	movwf	LED4		; 				

	call	PAUSE5s

StolbLED1off
	call	PAUSE05s	; Пауза 0,5 сек.		
								;
	decfsz	LED1,1		;
	goto	StolbLED1off

	movlw	0h
	movwf	LED1

	call	PAUSE5s

StolbLED2off
	call	PAUSE05s	; Пауза 0,5 сек.		
								;
	decfsz	LED2,1		;
	goto	StolbLED2off

	movlw	0h
	movwf	LED2

	call	PAUSE5s

StolbLED3off
	call	PAUSE05s	; Пауза 0,5 сек.

	decfsz	LED3,1		;
	goto	StolbLED3off

	movlw	0h
	movwf	LED3

	call	PAUSE5s

StolbLED4off
	call	PAUSE05s	; Пауза 0,5 сек.

	decfsz	LED4,1		;
	goto	StolbLED4off

	movlw	0h		; 
	movwf	LED4		; 				

	call	PAUSE1s


	decfsz	Povtor,1	; Зацикливаемся
	goto	StolbLED1on


;-------------------------------; Два бегущих огня
DvaBeg
	movlw	.7
	movwf	Povtor		; Повторить хх раз

	clrf	LED1
	clrf	LED2
	clrf	LED3
	clrf	LED4

DvaBegZazyg
;	call	GIRLemul	; Эмуляция гирлянды		; Подготовка
	call	PAUSE01s	; Пауза 0,1 сек.			;
	call	PAUSE01s	; Пауза 0,1 сек.			;
	call	PAUSE01s	; Пауза 0,1 сек.			;

	incfsz	LED4,1									;
	nop
	incfsz	LED1,1		; Плавно увеличиваю яркость	;
	goto	DvaBegZazyg	; до максимума			;
	movlw	0FFh;
	movwf	LED1
	movwf	LED4

DvaBegS12
	call	PAUSE01s
	decfsz	LED1,1
	nop
	incfsz	LED2,1
	goto	DvaBegS12
	movlw	0FFh
	movwf	LED2
	clrf	LED1
	call	PAUSE5s

DvaBegS23
	call	PAUSE01s
	decfsz	LED2,1
	nop
	incfsz	LED3,1
	goto	DvaBegS23
	movlw	0FFh
	movwf	LED3
	clrf	LED2
	call	PAUSE5s

DvaBegS34
	call	PAUSE01s
	decfsz	LED4,1
	nop
	incfsz	LED1,1
	goto	DvaBegS34
	movlw	0FFh
	movwf	LED1
	clrf	LED4
	call	PAUSE5s

DvaBegS45
	call	PAUSE01s
	decfsz	LED1,1
	nop
	incfsz	LED2,1
	goto	DvaBegS45
	movlw	0FFh
	movwf	LED2
	clrf	LED1
	call	PAUSE5s

DvaBegS56
	call	PAUSE01s
	decfsz	LED2,1
	nop
	incfsz	LED4,1
	goto	DvaBegS56
	movlw	0FFh
	movwf	LED4
	clrf	LED2
	call	PAUSE5s

DvaBegS67
	call	PAUSE01s
	decfsz	LED3,1
	nop
	incfsz	LED2,1
	goto	DvaBegS67
	movlw	0FFh
	movwf	LED2
	clrf	LED3
	call	PAUSE5s

DvaBegS78
	call	PAUSE01s
	decfsz	LED4,1
	nop
	incfsz	LED1,1
	goto	DvaBegS78
	movlw	0FFh
	movwf	LED1
	clrf	LED4
	call	PAUSE5s

DvaBegS89
	call	PAUSE01s
	decfsz	LED1,1
	nop
	incfsz	LED3,1
	goto	DvaBegS89
	movlw	0FFh
	movwf	LED3
	clrf	LED1
	call	PAUSE5s

DvaBegS9A
	call	PAUSE01s
	decfsz	LED3,1
	nop
	incfsz	LED4,1
	goto	DvaBegS9A
	movlw	0FFh
	movwf	LED4
	clrf	LED3
	call	PAUSE5s

DvaBegSAB
	call	PAUSE01s
	decfsz	LED2,1
	nop
	incfsz	LED1,1
	goto	DvaBegSAB
	movlw	0FFh
	movwf	LED1
	clrf	LED2
	call	PAUSE5s

DvaBegSBC
	call	PAUSE01s
	decfsz	LED4,1
	nop
	incfsz	LED2,1
	goto	DvaBegSBC
	movlw	0FFh
	movwf	LED2
	clrf	LED4
	call	PAUSE5s

DvaBegSCD
	call	PAUSE01s
	decfsz	LED2,1
	nop
	incfsz	LED3,1
	goto	DvaBegSCD
	movlw	0FFh
	movwf	LED3
	clrf	LED2
	call	PAUSE5s

DvaBegSDE
	call	PAUSE01s
	decfsz	LED3,1
	nop
	incfsz	LED4,1
	goto	DvaBegSDE
	movlw	0FFh
	movwf	LED4
	clrf	LED3
	call	PAUSE5s


	decfsz	Povtor,1	; Зацикливаемся
	goto	DvaBegS12

	goto	BegOgniRezk


;-------------------------------; Пауза 15с
PAUSE15s
	call	PAUSE5s
	call	PAUSE5s
	call	PAUSE5s
	return
;-------------------------------; end

;-------------------------------; Пауза 5с
PAUSE5s
	call	PAUSE1s
	call	PAUSE1s
	call	PAUSE1s
	call	PAUSE1s
	call	PAUSE1s
	return
;-------------------------------; end

;-------------------------------; Пауза 1с
PAUSE1s
        movlw   .255		;пауза для 1 сек
        movwf   PauseCntA
P1	movlw   .255
        movwf   PauseCntB
P2	decfsz  PauseCntB,1
        goto    P2
	nop
	decfsz  PauseCntA,1
        goto    P1
	nop
	return
;-------------------------------; end


;-------------------------------; Пауза 0,5с
PAUSE05s
	call	PAUSE01s
	call	PAUSE01s
	call	PAUSE01s
	call	PAUSE01s
	call	PAUSE01s
	return
;-------------------------------; end


;-------------------------------; Пауза 1с
PAUSE01s
        movlw   .2		;пауза для 0,1 сек
        movwf   PauseCntA
P01A	movlw   .220
        movwf   PauseCntB
P01B	decfsz  PauseCntB,1
        goto    P01B
	nop
	decfsz  PauseCntA,1
        goto    P01A
	nop
	return
;-------------------------------; end

	org	07FFh
	goto	start

	END
