

;************************** Registros especiales ******************************

status		equ		03h
porta		equ		05h
portb		equ		06h
portc		equ		07h
portd		equ		08h
porte		equ		09h
intcon		equ		0bh
pir1		equ		0ch
tmr1l		equ		0eh
tmr1h		equ		0fh	
t1con		equ		10h

trisa		equ		85h
trisb		equ		86h
trisc		equ		87h
trisd		equ		88h
trise		equ		89h
pie1		equ		8ch


;************************** Registros de usuario *******************************

contador	equ		20h		; contiene la variable del pulsador
loop		equ		21h
loop1		equ		22h		; loop y loop1 registros para rutina de tiempo 
						; antirebote
parpadeo	equ		23h		; controla la frecuencia


;************************** Empieza el programa ********************************

	list p = 16f877

	org	00
	goto	inicio

	org	04
	goto	inter

;************************* Rutina de manejo de interrupcion *********************

inter	btfsc	pir1,0
	goto	trata			; si detecto interrupcion va a trata
	retfie				; si no retorna al pcl + 1

trata	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'1'			; compara con uno
	btfsc	status,2
	goto	rojo
	goto	trata2			; si no voy a preguntar por el color naranja

rojo	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga
	movlw	b'10101111'
	movwf	tmr1l
	movlw	b'00111100'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 400ms (2.5Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 400ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga	movlw	b'10101111'
	movwf	tmr1l
	movlw	b'00111100'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 400ms (2.5Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 400ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie	

;************************* color naranja ***********************************

trata2	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'2'			; compara con uno
	btfsc	status,2
	goto	naranja			; si el contador no es dos voy a trata3
	goto	trata3

naranja	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga2
	movlw	b'01010111'
	movwf	tmr1l
	movlw	b'10011110'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 200ms (5.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 400ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga2	movlw	b'01010111'
	movwf	tmr1l
	movlw	b'10011110'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 200ms (5.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 400ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie	
 	
;************************* color amarillo ***************************************

trata3	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'3'			; compara con uno
	btfsc	status,2
	goto	amarillo		; si el contador es 3 a amarillo
	goto	trata4			; si el contador no es voy a trata4

amarillo
	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga3
	movlw	b'00101011'
	movwf	tmr1l
	movlw	b'11001111'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 100ms (10.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 400ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga3	movlw	b'00101011'
	movwf	tmr1l
	movlw	b'11001111'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 100ms (10.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 400ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie

;************************* Color Verde ******************************************

trata4	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'4'			; compara con uno
	btfsc	status,2
	goto	verde			; si es 4 voy a verde
	goto	trata5			; si el contador no es voy a trata5
	
verde	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga4
	movlw	b'10010101'
	movwf	tmr1l
	movlw	b'11100111'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 50ms (20.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 400ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga4	movlw	b'10010101'
	movwf	tmr1l
	movlw	b'11100111'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 50ms (20.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 400ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie

;************************* color azul *******************************************

trata5	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'5'			; compara con uno
	btfsc	status,2
	goto	azul			; si el contador es 5 voy a azul
	goto	trata6			; si el contador no es voy a trata6

azul	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga5
	movlw	b'11001010'
	movwf	tmr1l
	movlw	b'11110011'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 25ms (40.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 25ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga5	movlw	b'11001010'
	movwf	tmr1l
	movlw	b'11110011'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 25ms (40.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 25ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie

;************************* color azul indigo ************************************

trata6	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'6'			; compara con uno
	btfsc	status,2
	goto	azulindigo		; si el contador es 5 voy a azulindigo
	goto	trata7			; si el contador no es voy a trata7

azulindigo
	
	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga6
	movlw	b'11100101'
	movwf	tmr1l
	movlw	b'11111001'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 12.5ms (80.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 12.5ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga6	movlw	b'11100101'
	movwf	tmr1l
	movlw	b'11111001'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 12.5ms (80.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 12.5ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie

;************************* color Violeta **********************************************

trata7	movf	contador,0		; pasa el dato del contador a w
	xorlw	d'7'			; compara con uno
	btfsc	status,2
	goto	violeta			; si el contador es 5 voy a azulindigo
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie				; salgo de la interrupcion

violeta	incf	parpadeo,1		; incremento parpadeo en uno
	movf	parpadeo,0		; paso el valor a w
	xorlw	d'1'			; comparo con uno
	btfss	status,2
	goto	apaga7
	movlw	b'11110010'
	movwf	tmr1l
	movlw	b'11111100'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 6.25ms (160.0Hz)
	bsf	portb,1	
	bsf	portb,2	
	bsf	portb,3
	bsf	portb,4			; prendo el respectivo led por 6.25ms
	bsf	portb,5
	bsf	portb,6
	bsf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion
	retfie

apaga7	movlw	b'11110010'
	movwf	tmr1l
	movlw	b'11111100'
	movwf	tmr1h			; cargo los valores en tmr1l y tmr1h 
					; para garantizar 6.25ms (160.0Hz)
	bcf	portb,1	
	bcf	portb,2	
	bcf	portb,3
	bcf	portb,4			; apago el respectivo led por 6.25ms
	bcf	portb,5
	bcf	portb,6
	bcf	portb,7	
	bcf	pir1,0			; limpio la bandera de interrupcion	
	clrf	parpadeo
	retfie



;************************* Rutina de tiempo antirebote **************************

retar	movlw	d'100'
	movwf	loop
	movlw	d'100'
	movwf	loop1
	decfsz	loop1,1
	goto	$-1
	decfsz	loop,1
	goto	$-5
	return


;************************* Rutina principal de inicio ***************************

inicio	bcf	status,6
	bsf	status,5		; banco 1
	movlw	b'11111111'
	movwf	trisa
	movwf	trisc	
	movwf	trisd
	movwf	trise			; puertos A,C,D,E como entradas digitales
	movlw	b'00000001'
	movwf	trisb			; configuro el puerto B
	movlw	b'00000001'
	movwf	pie1			; habilito la interrupcion por el timer 1

	bcf	status,5		; banco 0
	movlw	b'00110001'
	movwf	t1con			; configuro el timer 1
	movlw	b'11000000'
	movwf	intcon			; habilito la interrupcion global y por perifericos
	clrf	portb
	clrf	contador
	clrf	parpadeo
vuelve	btfsc	portb,0			; pregunto por el pulsador
	goto	$-1			; si no esta vuelvo y pregunto
	call	retar
	btfss	portb,0			; pregunto si ya lo solto
	goto	$-1
	incf	contador,1		; incremento el contador en 1
	movf	contador,0		; paso el valor del contador a w
	xorlw	d'8'			; comparo con 8 para volver a empezar
	btfss	status,2		; pregunto por el resultado lgico
	goto	vuelve			; vuelve y inicia
	clrf	contador		; vuelvo a iniciar el ciclo
	bcf	portb,7			; limpio el ultimo led
	goto	vuelve
	end
	
	