;//////////////////Encabezado///////////////////////////////////////////////////////////////
; Temporizador DC variable - por MGD "MaMu" 2006/2007
; Editado y Compilado con MPLAB 7.50
; Testeado con Proteus ISIS Professional - release 6.7 (SP3)
;///////////////////////////////////////////////////////////////////////////////////////////

	list      p=16F84A     
	list c=132        			;Listado a 132 caracteres      
	#include <p16F84A.inc>  
	radix   hex

;//////////////////Configs//////////////////////////////////////////////////////////////////

__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

;/////////////////Definiciones//////////////////////////////////////////////////////////////

;Banco 0
#DEFINE	BANCO0			bcf		STATUS,RP0		; selecciono Banco 0 
#DEFINE	BANCO1			bsf		STATUS,RP0		; selecciono Banco 1
#DEFINE	IRQ_ENABLE		bsf		INTCON,GIE		; habilitamos todas las interrupciones
#DEFINE	IRQ_DISABLE		bcf		INTCON,GIE		; deshabilitamos todas las interrupciones
#DEFINE	RB47_ENABLE		bsf		INTCON,RBIE		; interrupcion PORTB pines RB4..RB7 On
#DEFINE	RB47_DISABLE	bcf		INTCON,RBIE		; interrupcion PORTB pines RB4..RB7 Off
#DEFINE	TMR0_ENABLE		bsf		INTCON,T0IE		; interrupcion TMR0 activada
#DEFINE	TMR0_DISABLE	bcf		INTCON,T0IE		; interrupcion TMR0 desactivada
#DEFINE	EXT_ENABLE		bsf		INTCON,INTE		; que sean interrupciones externas
#DEFINE	EXT_DISABLE		bcf		INTCON,INTE		; que sean interrupciones externas
#DEFINE	EEPROM_ENABLE	bsf		INTCON,EEIE		; interrupcion EEPROM activada
#DEFINE	EEPROM_DISABLE	bcf		INTCON,EEIE		; interrupcion EEPROM desactivada
#DEFINE	CLR_TOIF		bcf		INTCON,T0IF		; limpia flag TMR0
#DEFINE	CLR_INTF		bcf		INTCON,INTF		; limpia flag EXT, RB0
#DEFINE CLR_RBIF		bcf		INTCON,RBIF		; limpia flag RB4..RB7
;Banco 1
#DEFINE CLR_EEIF		bcf		EECON1,EEIF		; limpia flag EEIF, escritura en EEPROM

;/////////////////variables////////////////////////////////////////////////////////////////	

MEML	equ	0x30		;
MEME	equ	0x31		; EEPROM
DATOE	equ	0x32		;

contL1	equ	0x10		; contador despliegue Linea 1
contL2	equ	0x10		; contador despliegue Linea 2

segtcu	equ	0x09		; segundos del TC
segtcd	equ	0x05
mint1u	equ	0x00		; valores T1
mint1d	equ	0x00
hort1u	equ 0x02
hort1d	equ	0x01
segt1u	equ	0x09
segt1d	equ 0x05
mint2u	equ 0x00		; valores T2
mint2d	equ	0x00
hort2u	equ	0x02
hort2d	equ	0x01
segt2u	equ	0x09
segt2d	equ 0x05

auxT2 	equ	0x33
BLS		equ	0x00		; Back Ligth Status

;//////////////programa////////////////////////////////////////////////////////////////////
	
reset	ORG     0x00
	   	goto 	inicio

		ORG     0x04
		goto	INTERR

;////////////////////Librerias Externas///////////////////////////////////////////////////
	#include <lcd_4bit.inc>
	#include <retardos.inc>
;////////////////////Tablas///////////////////////////////////////////////////////////////

TablaL1	addwf	PCL,F				; se incrementa el contador de programa
		nop
		retlw	b'01010100'			; T
		retlw	b'00110001'			; 1
		retlw	b'00111101'			; :
		retlw	0x30+hort1d			; 1
		retlw	0x30+hort1u			; 2
		retlw	b'00111010'			; :
		retlw	0x30+mint1d			; 0
		retlw	0x30+mint1u			; 0
		retlw	b'00111010'			; :
		retlw	0x30+segt1d			; 0
		retlw	0x30+segt1u			; 0
		retlw	b'00101101' 		; -
		retlw	b'00101101' 		; -

TablaL2	addwf	PCL,F				; se incrementa el contador de programa
		nop
		retlw	b'01010100'			; T
		retlw	b'00110010'			; 2
		retlw	b'00111101'			; :
		retlw	0x30+hort2d			; 1
		retlw	0x30+hort2u			; 2
		retlw	b'00111010'			; :
		retlw	0x30+mint2d			; 0
		retlw	0x30+mint2u			; 0
		retlw	b'00111010'			; :
		retlw	0x30+segt2d			; 0
		retlw	0x30+segt2u			; 0
		retlw	b'00101101' 		; -
		retlw	b'00101101' 		; -

TablaBKT1	addwf	PCL,F			; para guardar en la EEPROM T1
			retlw	segt1u
			retlw	segt1d
			retlw	mint1u
			retlw	mint1d
			retlw	hort1u
			retlw	hort1d

TablaBKT2	addwf	PCL,F			; para guardar en la EEPROM T2
			retlw	segt2u
			retlw	segt2d
			retlw	mint2u
			retlw	mint2d
			retlw	hort2u
			retlw	hort2d

;/////////////////Interrupciones//////////////////////////////////////////////////////////

irq		IRQ_ENABLE			; habilito GIE
		
		return
;//////////////////Inicializacion de variables////////////////////////////////////////////

init	clrf	TMR0		; limpio TMR0
		clrf	MEME		; limpio addr de la EEPROM, escritura
		clrf	MEML		; limpio addr de la EEPROM, lectura
		clrf	auxT2		; limpio aux de la EEPROM, backupT2
		clrf	BLS			; limpio Back Ligth Status
		return
;///////////////Configuración de PUERTOS///////////////////////////////////////////////////


inicio	BANCO1
		movlw	b'01000'		;puerto A como salida, salvo RA2 entrada
		movwf	TRISA
		movlw	b'00001111'		;RB0-3 Entradas, RB4-7 Salidas
		movwf	TRISB
		BANCO0
		clrf	PORTA			;limpio Puerto A
		clrf	PORTB			;limpio Puerto B
;///para las Interrupciones///
		BANCO1
		movlw	b'00000111'		; 1:256 como prescaler, Pull Up RB conectadas
		movwf	OPTION_REG
		BANCO0
;////Para el LCD///
		call	irq				; habilito las interrupciones que quiera
		call	init			; inicio variables y contadores
		call	VERIFICA		; hay datos en la EEPROM? o es la primera vez? Sino, los carga
		call	LCD_Inicializa  ; inicializa el display de LCD

		bcf		INTCON,2
		movlw	0xD8			; que valor al TMR0? (uso el complemento de lo que quiero)
		movwf	TMR0			; cargo TMR0 con .216
		TMR0_ENABLE				; habilito T0IE, INT de TMR0, (lo hago ahora, los ciclos de antes no cuentan
		
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>

main
call	VISUALIZA		; despliegue de datos en el LCD	
goto main
		                                                

;///////////////////////////Rutinas///////////////////////////////////////////////////////

VISUALIZA
Lin1	call	LCD_Linea1		; datos del T1 en linea 1
		clrf	contL1
bucle	movf	contL1,W
		xorlw	b'1101'			; verifica si el contador llegó a 13
		btfsc	STATUS,Z		; si no es así salta una línea
		goto	Lin2	 		; si llegó a 13 termino y empieza T2
		incf	contL1,F		; incrementa el contador
		movf	contL1,W		; pasa el contador a w (índice)
		call	TablaL1			; llama a la tabla
		call	LCD_Caracter	; sale caracter por pantalla
		goto	bucle		
		
Lin2	clrf	contL2			; datos del T2 en linea 2
		call	LCD_Linea2	
ciclo	movf	contL2,W
		xorlw	b'1101'			; verifica si el contador llegó a 13
		btfsc	STATUS,Z		; si no es así salta una línea
		return					; si llegó a 13 termino y retorna a donde sea...
		incf	contL2,F		; incrementa el contador
		movf	contL2,W		; pasa el contador a w (índice)
		call	TablaL2			; llama a la tabla
		call	LCD_Caracter	; sale caracter por pantalla
		goto	ciclo


RESTORE		call	RELOADT1
			call	RELOADT2
			return

RELOADT1	movlw	0x00		; recupera valores de T1 de la EEPROM
			movwf	MEML
			call	LECTURA
			movwf	segt1u
			movlw	0x01
			movwf	MEML
			call	LECTURA
			movwf	segt1d	
			movlw	0x02
			movwf	MEML
			call	LECTURA
			movwf	mint1u	
			movlw	0x03
			movwf	MEML
			call	LECTURA
			movwf	mint1d	
			movlw	0x04
			movwf	MEML
			call	LECTURA
			movwf	hort1u
			movlw	0x05
			movwf	MEML
			call	LECTURA
			movwf	hort1d
			return

RELOADT2	movlw	0x10		; recupera valores de T2 de la EEPROM
			movwf	MEML
			call	LECTURA
			movwf	segt2u
			movlw	0x11
			movwf	MEML
			call	LECTURA
			movwf	segt2d	
			movlw	0x12
			movwf	MEML
			call	LECTURA
			movwf	mint2u	
			movlw	0x13
			movwf	MEML
			call	LECTURA
			movwf	mint2d	
			movlw	0x14
			movwf	MEML
			call	LECTURA
			movwf	hort2u
			movlw	0x15
			movwf	MEML
			call	LECTURA
			movwf	hort2d
			return
			

VERIFICA	movlw	0x00			; hay datos cargados en la EEPROM?
			movwf	MEML
			call	LECTURA
			xorlw	0xFF
			btfss	STATUS,Z
			call	RESTORE
			call	BUP				; sino, los carga
			CLR_TOIF
			return

BUP			call	BACKUPT1
			call	BACKUPT2
			return	

BACKUPT1	movlw	0x0				; T1=12:00:59
			movwf	MEME
cicloT1		movfw	MEME
			call	TablaBKT1
			movwf	DATOE
			call	ESCRITURA
			incf	MEME,F
			movfw	MEME
			xorlw	b'0110'
			btfss	STATUS,Z
			goto 	cicloT1
			return

BACKUPT2	movlw	0x10			; T2=12:00:59
			movwf	MEME
			movlw	0x00
cicloT2		movfw	auxT2
			call	TablaBKT2
			movwf	DATOE
			call	ESCRITURA
			incf	MEME,F
			movfw	MEME
			incf	auxT2,F
			
			movfw	auxT2
			xorlw	b'0110'
			btfss	STATUS,Z
			goto 	cicloT2
			return

;///////////////////////////Rutinas IRQ///////////////////////////////////////////////////

INTERR	btfss  INTCON,T0IF			; la int es TMR0 ?
		goto	sale				; no es, es otra asi que sale
		goto	muestra				; es!!! la atiende
		goto	sale				; despues sale...

muestra  movlw	0x05							; HAGO LAS CUENTAS
		 movwf	hort1u	
	     movf	hort1u,W
         goto	sale

sale	CLR_TOIF					;limpio la bandera que sea, ahora TMR0
		clrf	TMR0				; recargo el TMR0 para el proximo disparo
		movlw	0xD8
		movwf	TMR0
		retfie	
;/////////////////////Botones-Entradas////////////////////////////////////////////////////

BACKLIGHT	btfss	PORTA,3		; esta en 1? encendido BackLigth
			goto	BLON		; lo prende
			goto	BLOFF		; lo apaga
			return

BLON	btfsc	BLS,0
		goto	BLOFF_
		goto	BLON_
		return

BLOFF	btfss	BLS,0
		goto	BLOFF_
		goto	BLON_
		return


BLON_	bsf		PORTA,1
		bsf		BLS,0
		return

BLOFF_	bcf		PORTA,1
		clrf	BLS
		return

PULSAHT1	btfss	PORTB,0					; ACA DEJE... NO VA, es prueba nomas
			goto	suma
			return

suma    bsf PORTA,4	
		return

;/////////////////////Accesso a EEPROM////////////////////////////////////////////////////

LECTURA	BANCO0   			    ; Selecciona banco 0
        movfw 	MEML            ; Dirección a leer de la EEPROM
        movwf 	EEADR
        BANCO1 	  			 	; Selecciona banco 1
        bsf 	EECON1,RD    	; Activar Lectura
ESPERAL btfsc 	EECON1,RD       ; Espera final de lectura
        goto 	ESPERAL
        BANCO0    				; Selecciona banco 0
        movf 	EEDATA,W    	; W se carga con el valor leído en EEPROM
		return

ESCRITURA	BANCO0    		      ; Selecciona el banco 0
			IRQ_DISABLE			  ; deshabilito todas las interrupciones
			movfw	MEME  
			movwf 	EEADR    	  ; Escribe la dirección en EEADR
			movfw 	DATOE
			movwf 	EEDATA   	  ; Se escribe el dato en EEDATA
			BANCO1			  	  ; Selecciona el banco 1
			bsf 	EECON1,WREN   ; Permiso de escritura
								  ; Comienzo Secuencia de escritura
			movlw 	0x55
			movwf 	EECON2        ; Se escribe el dato 55h en eecon2
			movlw 	0xAA 
			movwf 	EECON2        ; Se escribe AA h en eecon2
			bsf 	EECON1,WR     ; Comienza la escritura
ESPERAE		btfsc 	EECON1,WR     ; Espera a que termine la escritura
			goto 	ESPERAE
			BANCO0         		  ; Selecciona el banco 0
			IRQ_ENABLE			  ; re habilito todas las interrupciones
			return
;///////////////////Rutinas de Retardos///////////////////////////////////////////////////


;//////////////////////////NOTAS//////////////////////////////////////////////////////////
;
;///EEPROM
;Un sistema para comprobar si se ha producido la escritura correctamente en la memoria 
;EEPROM consiste en restar el dato escrito con el que existe en el registro EEDATA. 
;Si no se ha producido error el flag Z pasa a valer 1.
;Microchip recomienda que se deshabiliten las interrupciones globales durante la secuencia 
;de R/W, añadiendo las instrucciones al principio y final de la secuencia.
;Proceso de verificación de la escritura. Dependiendo de la aplicación, es aconsejable 
;que se compruebe que los datos se están escribiendo correctamente aunque esto no suele 
;ser necesario en la mayoría de las ocasiones, para las posiciones de memoria EEPROM es 
;aconsejable.

;/////////////////////The End/////////////////////////////////////////////////////////////
END
