;Diseño
;Se desea realizar un reloj digital. En la figura 1 se muestra el esquema para
;implementar dicha aplicación, para esto debe colocar como visualización una
;pantalla de cristal liquido (LCD). Debe colocar pulsadores para modificar la hora y
;minuto (Verificar como funcionan los pulsadores para un reloj comercial). La base
;de tiempo debe llevarse con el timer 1 conectando un cristal a este y
;configurándolo como contador. Se recomienda utilizar un Cristal de 32.768 KHz.
;NOTA: El TIMER1 debe ser atendido por interrupciones.

list		p=16f877
include		<p16f877.inc>


Lcd_var		equ	0x20
n		equ	0x23
seg		equ	0x26
min		equ	0x27
hora		equ	0x28
Temporal		equ	0x29
Unidades		equ	0x2A
Decenas		equ	0x2B
VAR1		equ	0x2C
VAR2		equ	0x2D

org		0x00
goto		Inicio

org		0x04
goto		Inter

include		<LCD_PORTD.inc>

Inter		btfss	PIR1,TMR1IF
retfie
				
				
;INTERRUMPCION TMR0
SI_SEG
	bcf		INTCON,GIE
	bcf		PIR1,TMR1IF
	comf		PORTA,f		;Prende y apaga LED en RA0 cada segundo
	incf		seg,f		;Si paso el segundo
	movlw		.60
	subwf		seg,w
	btfss		STATUS,Z
	goto		Ini_hora
	clrf		seg		;Pasaran 60 Seg seg=0
	incf		min,f		;se incrementan los minutos
	movlw		.60
	subwf		min,w
	btfss		STATUS,Z
	goto		Ini_hora
	clrf		min		;Pasaron 60 Min min=0
	movlw		.12
	subwf		hora,w		;Las horas=12
	btfsc		STATUS,Z
	clrf		hora		;Si hora=12 se borra para luego ser llevada a hora=1
	incf		hora,f		;Se incrementan las horas

;Pregunta si esta presionado RB4
Ini_hora
	btfsc		PORTB,4
	goto		Inc_min
	call		RETARDO_10
	movlw		.12
	subwf		hora,w		;Las horas=12
	btfsc		STATUS,Z
	clrf		hora		;Si hora=12 se borra para luego ser llevada a hora=1
	incf		hora,f		;Se incrementan las horas
	goto		INI_SEG

;Pregunta si esta presionado RB5
Inc_min
	btfsc		PORTB,5
	goto		rei_seg
	call		RETARDO_10
	incf		min,f		;se incrementan los minutos
	movlw		.60
	subwf		min,w
	btfss		STATUS,Z
	goto		INI_SEG
	clrf		min		;Pasaron 60 Min min=0
	goto		INI_SEG

;Pregunta si esta presionado RB6
rei_seg
	btfsc		PORTB,6		;Reinicia el segundero a cero
	goto		INI_SEG
	call		RETARDO_10
	movlw		0x80
	movwf		TMR1H
	clrf		TMR1L
	clrf		seg
	movlw		0x9D
	call		LCD_REG
	movlw		'0'
	call		LCD_DATO
	movlw		'0'
	call		LCD_DATO


INI_SEG
	movlw		0x80
	movwf		TMR1H
	clrf		TMR1L
	call		MOSTRAR_HORA
	bcf		PIR1,TMR1IF


SALIR
	bsf		INTCON,GIE
	retfie


Inicio
	bsf		STATUS,RP0
	bcf		STATUS,RP1	;Banco 1
	movlw		.6
	movwf		ADCON1		;Puertos A y E E/S Digitales
	clrf		TRISA
	clrf		TRISD
	clrf		TRISE
	movlw		0xFF
	movwf		TRISB
	movwf		TRISC		;Puertos B y C como entradas
	clrf		OPTION_REG
	movlw		0x01
	movwf		PIE1		;Habilitar Interrupcion por Timer1
	bcf		STATUS,RP0	;Banco 0
	clrf		PORTA
	clrf		PORTD
	clrf		PORTE		;Borra latch de Salida
	clrf		seg
	clrf		min
	movlw		.12
	movwf		hora		;Inicializa la hora-> 12:00:00
	movlw		0x0F
	movwf		T1CON
	movlw		0x80
	movwf		TMR1H
	clrf		TMR1L		;Se carga con 32768 el TIMER1
	movlw		b'11000000'	;Habilita la interrupcion
	movwf		INTCON		;por Timer1
	bcf		PIR1,TMR1IF	;Inicializar la bandera en 0


;Inicializa la LCD que esta conectada por el puerto D y
;Muestra los mensajes en la pantalla
call		UP_LCD		;Configura puerto para el LCD
call		LCD_INI		;Inicia el LCD
movlw		b'00001100'
call		LCD_REG		;LCD On, cursor y blink Off
call		MOSTRAR_HORA
bucle		clrwdt
nop
goto		bucle
					

;*********************************************************
;*********************************************************


;Sub rutina para convertir numeros decimales a BCD

Conver
	movwf		Temporal
	clrf		Decenas
	clrf		Unidades

Conver_1
	movlw		.10
	subwf		Temporal,f
	btfsc		3,0
	goto		INCREMENTAR
	movf		Temporal,w
	addlw		.10
	movwf		Unidades
	return

INCREMENTAR
	incf		Decenas,f
	goto		Conver_1


;*********************************************************
;*********************************************************				


RETARDO_10
	movlw		.4
	movwf		VAR1
	ciclo1
		movlw		.221
		movwf		VAR2
	ciclo2
		decfsz		VAR2,F
		goto		ciclo2
		decfsz		VAR1,F
		goto		ciclo1
	return


;*********************************************************
;*********************************************************				


MOSTRAR_HORA
	movlw		0x97
	call		LCD_REG
	movf		hora,w
	call		Conver
	movf		Decenas,w
	iorlw		0x30
	call		LCD_DATO
	movf		Unidades,w
	iorlw		0x30
	call		LCD_DATO
	movlw		':'
	call		LCD_DATO
	movf		min,w
	call		Conver
	movf		Decenas,w
	iorlw		0x30
	call		LCD_DATO
	movf		Unidades,w
	iorlw		0x30
	call		LCD_DATO
	movlw		':'
	call		LCD_DATO
	movf		seg,w
	call		Conver
	movf		Decenas,w
	iorlw		0x30
	call		LCD_DATO
	movf		Unidades,w
	iorlw		0x30
	call		LCD_DATO
	return


;*********************************************************
;*********************************************************	
				
end