list p=16F870
include "p16f870.inc"
;*********** definicion de parametros**********
PUERTOA equ 0x05
PUERTOB equ 0x06
PUERTOC equ 0x07

;**************************************************
;		DEFINICION DE VARIABLES
;**************************************************
RDELAY  equ 0x21
CONTA0  equ 0x22
CONTA1  equ 0x23
CONTA2  equ 0x24
letra   equ 0x25
flinea  equ 0x26
UNIDADES	EQU	27H
DECENAS		EQU	28H
CENTENAS	EQU	29H
MILLARES	EQU	2AH
D_MILLAR	EQU	2BH
C_MILLAR	EQU	2CH
TEMP		EQU	2DH
DELAY_LCD	EQU	2EH
DELAY_LCD1	EQU	2FH
DELAY_LCD2	EQU	30H
ADDRESS_EE	EQU	31H
EEPROM_DATA	EQU	32H
TECLA		EQU	33H

;***********  constantes para el LCD******
linea1LCD   equ 0x80
linea2LCD   equ 0xC0
clrLCD      equ 0x01
casaLCD     equ 0x02
incLCD      equ 0x07
decLCD      equ 0x05
onLCD       equ 0x0C
ofLCD       equ 0x08
oncursor    equ 0x0E
offcursor   equ 0x0C
blinkcursor equ 0x0F
izqLCD      equ 0x18
derLCD      equ 0x1C
izqcursor   equ 0x10
dercursor   equ 0x14
funcionLCD  equ 0x38
RS          equ 0
E           equ 2
W           equ 0
F           equ 1
BUZZER	    equ 5

;******** definiciones *******
#define banco0       bcf STATUS,RP0  ; pasa al banco 0
#define banco1       bsf STATUS,RP0 ; pasar al banco 1
#define act_int_gen  bsf INTCON,GIE ; habilitar interrupcion global
#define act_RB0      bsf INTCON,INTE ; habilitar interrupcion por RB0
#define lim_ban_RB0  bcf INTCON,INTF ; Limpia la bandera de interrupcion por RB0

		ORG		2100H
		DE		0,0,0,0,2,0	;Valor inicial del valor a comparar con el contador (datos almacenados en EEPROM)
org 0x00
goto iniciar
org 0x04        ; vector de interrupciones 
goto interrupcion 

; *****************PROGRAMA PRINCIPAL**********************
;                  ******************
iniciar     call   port_LCD		;Inicializa el puerto de la LCD
            call   ini_LCD		;Inicializa la LCD
	    CALL   inicio_matricial	;Inicializa el puerto del teclado matricial
rb1         movlw  linea1LCD     ; poner senal para empezar a mandar datos
            call   comandoLCD
            movlw  0x0f          ;w=15 para 15 datos
            movwf  flinea        ; registro flinea=15
            clrf   letra         ; registro que va a moverse sobre la tabla
rb2         movf   letra,W       ; muestra el mensaje
            call   mensaje  
            call   caracterLCD    ; manda el caracter al LCD
            incf   letra,F        ; f=1 en el registro si f=0 en w
            decfsz flinea,F
            goto rb2
	    MOVLW  linea2LCD	;Coloca el cursor en la segunda linea de la LCD
	    CALL   comandoLCD
	    MOVLW  2CH		;Prepara el apuntador para la variable C_MILLAR
	    MOVWF  FSR
	    MOVLW  0		;Prepara la direccion 0 de la EEPROM
	    MOVWF  ADDRESS_EE
LEER_TECLADO
	    CALL   codificacion		;Realiza lectura del teclado
	    MOVWF  TECLA		;Carga el posible valor de la tecla presionada
	    XORLW  0
	    BTFSC  STATUS,Z		;Se presiono alguna tecla?
	    GOTO   LEER_TECLADO		;No, entonces continua leyendo el teclado
	    MOVF   TECLA,W		;Si, entonces asigna el valor de tecla
	    XORLW  '#'
	    BTFSC  STATUS,Z		;La tecla presionada fue "#"?
            GOTO   LEER_TECLADO		;Si, entonces ignora esa tecla y continua leyendo el teclado
	    MOVF   TECLA,W
	    XORLW  '*'
	    BTFSC  STATUS,Z		;No. La tecla presionada fue "*"?
	    GOTO   LEER_TECLADO 	;Si, entonces ignora esa tecla y continua leyendo el teclado
	    MOVF   TECLA,W		
	    MOVWF  INDF			;Carga en RAM el valor de la tecla presionada
	    MOVWF  letra
	    CALL   caracterLCD		;Coloca el valor de la tecla presionada en la LCD
	    BSF    PUERTOA,BUZZER	;Activa buzzer para generar un beep por tecla presionada
	    CALL   DELAY_50MS
	    CALL   DELAY_50MS
	    BCF    PUERTOA,BUZZER	;Desactiva el buzzer
GRABAR_EEPROM
	    MOVF   TECLA,W		;Prepara el dato a escribir
	    MOVWF  EEPROM_DATA
	    MOVLW  30H			;Convierte el dato ASCII a su valor BCD
	    SUBWF  EEPROM_DATA,F
	    MOVF   ADDRESS_EE,W		;Prepara la direccion en donde escribir
	    CALL   WR_EEPROM		;Escribe el dato en EEPROM
	    CALL   rebote		;Elimina los rebotes de la tecla presionada
	    INCF   ADDRESS_EE,F		;Incrementa la direccion en donde escribir
	    DECF   FSR,F		;Decrementa el apuntador de RAM
	    MOVLW  26H
            XORWF  FSR,W
	    BTFSS  STATUS,Z		;Ya se teclearon todos los digitos de la cuenta?
	    GOTO   LEER_TECLADO		;No, entonces continua leyendo el teclado
	    CALL   DELAY_500MS
	    CALL   DELAY_500MS
	    CALL   DELAY_500MS
	    banco1
	    BCF    OPTION_REG,INTEDG	;Genera interrupcion en RB0 por flanco de bajada
	    banco0
            act_int_gen		;Habilita la interrupcion general
	    lim_ban_RB0		;Limpia la bandera de interrupcion de RB0
            act_RB0		;Habilita la interrupcion en RB0
	    CLRF   UNIDADES	;Inicializa variables de contador en 000000
	    CLRF   DECENAS
	    CLRF   CENTENAS
	    CLRF   MILLARES
            CLRF   D_MILLAR
            CLRF   C_MILLAR
	    MOVLW  clrLCD	;Limpia la LCD
            CALL   comandoLCD
            CALL   DELAY_1MS
	    MOVLW  linea1LCD+1  ;Posiciona cursor en segunda columna del primer renglon de la LCD
	    CALL   comandoLCD
	    movlw  0x0f          ;w=15 para 15 datos
            movwf  flinea        ; registro flinea=14
            clrf   letra         ; registro que va a moverse sobre la tabla
rb3         movf   letra,W       ; muestra el mensaje
            call   mensaje1  
            call   caracterLCD    ; manda el caracter al LCD
            incf   letra,F        ; f=1 en el registro si f=0 en w
            decfsz flinea,F
            goto rb3
	    CALL   MUESTRA_CONTADOR
	    goto  $

;**********************************************************************
;		RUTINA DE INTERRUPCION
;**********************************************************************
interrupcion	INCF	UNIDADES,F		;Incrementa el valor de las unidades del contador
		MOVLW	.10			
		XORWF	UNIDADES,W		
		BTFSS	STATUS,Z		;Las unidades del contador es igual 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	UNIDADES		;Si, entonces reinicializa las unidades en cero
		INCF	DECENAS,F		;Incrementa el valor de las decenas del contador
		MOVLW	.10
		XORWF	DECENAS,W
		BTFSS	STATUS,Z		;Las decenas del contador es igual 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	DECENAS			;Si, entonces reinicializa las decenas en cero
		INCF	CENTENAS,F		;Incrementa el valor de las centenas del contador
		MOVLW	.10
		XORWF	CENTENAS,W
		BTFSS	STATUS,Z		;Las centenas del contador es igual 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	CENTENAS		;Si, entonces reinicializa las centenas en cero
		INCF	MILLARES,F		;Incrementa el valor de los millares del contador
		MOVLW	.10
		XORWF	MILLARES,W
		BTFSS	STATUS,Z		;Los millares del contador es igual a 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	MILLARES		;Si, entonces reinicializa los millares en cero
		INCF	D_MILLAR,F		;Incrementa el valor de las decenas de millar del contador
		MOVLW	.10
		XORWF	D_MILLAR,W
		BTFSS	STATUS,Z		;Las decenas de millar del contador es igual a 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	D_MILLAR		;Si, entonces reinicializa las decenas de millar en cero
		INCF	C_MILLAR,F		;Incrementa el valor de las centenas de millar del contador
		MOVLW	.10
		XORWF	C_MILLAR,W
		BTFSS	STATUS,C		;Las centenas de millar es igual a 10?
		GOTO	COMPARAR_CONTADOR	;No, entonces ve a comparar el contador actual con el programado
		CLRF	C_MILLAR		;Si, entonces reinicializa las centenas de millar en cero
COMPARAR_CONTADOR
		CLRW				;Prepara la direccion 0 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las centenas de millar en la EEPROM a comparar
		XORWF	C_MILLAR,W
		BTFSS	STATUS,Z		;Las centenas de millar del contador es igual a las centenas dl millar de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
		MOVLW	.1			;Si, entonces prepara la direccion 1 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las decenas de millar en la EEPROM a comparar
		XORWF	D_MILLAR,W
		BTFSS	STATUS,Z		;Las decenas de millar del contador es igual a las decenas de millar de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
		MOVLW	.2			;Si, entonces prepara la direccion 2 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las unidades de millar en la EEPROM a comparar
		XORWF	MILLARES,W
		BTFSS	STATUS,Z		;Las unidades de millar del contador es igual a las unidades de millar de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
		MOVLW	.3			;Si, entonces prepara la direccion 3 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las centenas en la EEPROM a comparar
		XORWF	CENTENAS,W
		BTFSS	STATUS,Z		;Las centenas del contador es igual a las centenas de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
		MOVLW	.4			;Si, entonces prepara la direccion 4 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las decenas en la EEPROM a comparar
		XORWF	DECENAS,W
		BTFSS	STATUS,Z		;Las decenas del contador es igual a las decenas de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
		MOVLW	.5			;Si, entonces prepara la direccion 5 de la EEPROM
		CALL	RD_EEPROM		;Realiza la lectura de las unidades en la EEPROM a comparar
		XORWF	UNIDADES,W
		BTFSS	STATUS,Z		;Las unidades del contador es igual a las unidades de la EEPROM?
		GOTO	MOSTRAR_CONTADOR_ACTUAL	;No, entonces ve a mostrar el contador actual
SIGUE_MOSTRANDO	BSF	PUERTOA,BUZZER		;Activa el buzzer
		CALL	MUESTRA_CONTADOR	;Muestra el valor del contador actual en la LCD
		CALL	DELAY_500MS
		BCF	PUERTOA,BUZZER		;Desactiva el buzzer
		MOVLW 	linea2LCD+5    ;Posiciona cursor en la 5 columna del segundo renglon de la LCD
	    	CALL	comandoLCD
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		MOVLW	' '
		CALL  	caracterLCD  	;Despliega el dato en el display
		CALL	DELAY_500MS
		GOTO	SIGUE_MOSTRANDO

MOSTRAR_CONTADOR_ACTUAL
		CALL	MUESTRA_CONTADOR	;Muestra el valor del contador actual en la LCD
		lim_ban_RB0			;Limpia la bandera de interrupcion en RB0
		RETFIE				;Termina la rutina de interrupcion
                        
; ********** MENSAJE***********

mensaje     addwf     PCL,1
            retlw     'R'   
            retlw     'A'   
            retlw     'N'  
            retlw     'G'  
            retlw     'O'  
            retlw     ' '  
            retlw     'A'  
            retlw     ' '
            retlw     'C'  
            retlw     'O'  
            retlw     'N'  
            retlw     'T'  
            retlw     'A'  
            retlw     'R'  
            retlw     '?'

  
; ********** MENSAJE***********

mensaje1    addwf     PCL,1
            retlw     'C'   
            retlw     'O'   
            retlw     'N'  
            retlw     'T'  
            retlw     'A'  
            retlw     'D'
	    retlw     'O'  
            retlw     'R'  
            retlw     ' '
            retlw     'A'  
            retlw     'C'  
            retlw     'T'  
            retlw     'U'  
            retlw     'A'  
            retlw     'L'
            
;             ************SUBRUTINAS**************
;                ******************************      
port_LCD    banco1
            movwf 0x06             ;configurar puertoa como E/S digital
            movwf ADCON1
            clrf  PUERTOA          ;configurar puertoa como salida 
            movlw 0xff
	    movwf PUERTOB
            clrf  PUERTOC          ;configurar  puertoc como salida 
            banco0
            bcf  PUERTOA,E        ;manda un 1 a pata E del LCD
            return 

ini_LCD     call   retardo          ;inicializa LCD
            movlw  funcionLCD       ;w 0x38
            call   comandoLCD   
            call   retardo
            movlw  funcionLCD       ;w 0x38
            call   comandoLCD   
            call   retardo
            movlw  funcionLCD       ;w 0x38
            call   comandoLCD   
            call   retardo
            movlw  funcionLCD       ;w 0x38
            call   comandoLCD   
            movlw  onLCD
            call   comandoLCD
            movlw  clrLCD
            call   comandoLCD
            movlw  decLCD
            call   comandoLCD
            movlw  casaLCD
            call   comandoLCD
            return

comandoLCD     bcf   PUERTOA,RS  ;manda un comando al LCD
               bcf   PUERTOA,E   ;entrada de habilitacion
               movwf PUERTOC
               call  habilitaLCD
               return

caracterLCD    bsf   PUERTOA,RS  ;manda un caracter al LCD
               bcf   PUERTOA,E   
               movwf PUERTOC
               call  habilitaLCD
               return

habilitaLCD    bsf    PUERTOA,E     ;manda caracter o dato al LCD
               movlw  0xFF
               movwf  RDELAY
t1             decfsz RDELAY,F 
               goto t1
               bcf PUERTOA,E
               return

retardo        movlw   0x01   ;retardo
               movwf   CONTA0
ret2           movlw   0x64
               movwf   CONTA1
ret1           movlw   0x64
               movwf   CONTA2
ret0           decfsz  CONTA2,F 
               goto    ret0
               decfsz CONTA1,F
               goto   ret1 
               decfsz CONTA0,F
               goto    ret2
               return 

;**************** SUBRUTINAs TECLADO MATRICIAL*********************
;                *************************

inicio_matricial        banco0                      ; pasa al banco 0
                        clrf PUERTOB                ; inicializando el puertoB
                        banco1                      ; pasa al banco 1
                        movlw 0xF1                  ;configura de rb7 a rb4 como entradas 
                        movwf TRISB                 ;y desde rb3 a rb1 como salidas rb0 como entrada
                        bcf OPTION_REG,7
                        banco0
                        return

rebote                  CALL	DELAY_50MS
			MOVF	PUERTOB,W	;Carga el contenido del puerto B en W
			ANDLW	0F0H		;Enmascara la parte alta del puerto B
			XORLW	0F0H
			BTFSS	STATUS,Z	;aun se esta presionando la tecla?
			GOTO	rebote		;Si, entonces realiza otro delay de 50 milisegundos
			CALL	DELAY_50MS	;No, realiza un delay de 50 milisegundos
			RETURN			;Termina la subrutina

codificacion            movlw 0xF7		;Habilita la columna 1
                        movwf PUERTOB
                        btfss PUERTOB,7		;Se ha presionado la tecla del "1"?
                        retlw '1'               ;Si, entonces regresa el ASCII del 1         
                        btfss PUERTOB,6		;Se ha presionado la tecla de "4"?
                        retlw '4'		;Si,entonces regresa el ASCII del 4
                        btfss PUERTOB,5		;Se ha presionado la tecla del "7"?
                        retlw '7'		;Si, entonces regresa el ASCII del 7
                        btfss PUERTOB,4		;Se ha presionado la tecla del "*"?
                        retlw '*'		;Si, entonces regresa el ASCII del *
                        movlw 0xFB		;Habilita la columna 2
                        movwf PUERTOB
                        btfss PUERTOB,7		;Se ha presionado la tecla del "2"?
                        retlw '2'		;Si, entonces regresa el ASCII del 2
                        btfss PUERTOB,6		;Se ha presionado la tecla del "5"?
                        retlw '5'		;Si, entonces regresa el ASCII del 5
                        btfss PUERTOB,5		;Se ha presionado la tecla del "8"?
                        retlw '8'		;Si, entonces regresa el ASCII del 8
                        btfss PUERTOB,4		;Se ha presionado la tecla del "0"?
                        retlw '0' 		;Si, entonces regresa el ASCII del 0
                        movlw 0xFD 		;Habilita la columna 3
                        movwf PUERTOB                                                                                      
                        btfss PUERTOB,7		;Se ha presionado la tecla del "3"?
                        retlw '3'		;Si, entonces regresa el ASCII del 3
                        btfss PUERTOB,6		;Se ha presionado la tecla del "6"?
                        retlw '6'		;Si, entonces regresa el ASCII del 6
                        btfss PUERTOB,5		;Se ha presionado la tecla del "9"?
                        retlw '9'		;Si, entonces regresa el ASCII del 9
                        btfss PUERTOB,4		;Se ha presionado la tecla del "#"?
                        retlw '#'		;Si, entonces regresa el ASCII del #
                        retlw 0x00 		;No, entonces regresa valor nulo

;**************************************************************************************************
;		SUBRUTINA PARA LEER UN DATO DE LA MEMORIA EEPROM DEL MICRO
;	ENTRADAS:	W (conteniendo la direccion a accesar)
;	SALIDAS:	W (conteniendo el dato leido de la EEPROM)
;**************************************************************************************************
RD_EEPROM	NOP
		BANKSEL	EEADR
		MOVWF	EEADR			;Carga la direccion a leer de la EEPROM
		BANKSEL	EECON1
		BCF	EECON1,EEPGD		;Habilita memoria de datos
		BSF	EECON1,RD		;Inicia lectura
		BANKSEL	EEDATA
		MOVF	EEDATA,W		;Carga dato leido de la EEPROM en W
		BANKSEL	ADCON0			;Cambia al banco 0
		RETURN				;Termina subrutina

;**************************************************************************************************
;		SUBRUTINA PARA ESCRIBIR UN DATO EN LA MEMORIA EEPROM DEL MICRO
;		ENTRADAS: W (contiene la direccion a escribir)
;			  EEPROM_DATA
;		SALIDAS:  NINGUNA
;**************************************************************************************************
WR_EEPROM	NOP
		BANKSEL	EEADR			;Cambia al banco 2
		MOVWF	EEADR			;Carga la direccion de la EEPROM a escribir
		BANKSEL	EEPROM_DATA		;Cambia al banco 0
		MOVF	EEPROM_DATA,W		;Carga en W el dato a escribir
		BANKSEL	EEDATA			;Cambia al banco 2
		MOVWF	EEDATA			;Carga el dato a escribir en EEPROM
		BANKSEL	EECON1			;Cambia al banco 3
		BCF	EECON1,EEPGD		;Habilita la memoria de datos
		BSF	EECON1,WREN		;Habilita la escritura de datos de la EEPROM
		BCF	INTCON,GIE		;Deshabilita todas las interrupciones
		MOVLW	55H			;Inicia secuencia de escritura
		MOVWF	EECON2
		MOVLW	0AAH
		MOVWF	EECON2
		BSF	EECON1,WR		;Inicia la escritura del dato en la EEPROM
ESPET		BTFSC	EECON1,WR		;Ya se escribio el dato?
		GOTO	ESPET
		BCF	EECON1,WREN		;Deshabilita la escritura de datos
		BANKSEL	ADCON0			;Cambia al banco 0
		RETURN				;Termina subrutina

;**************************************************************************************************
;		SUBRUTINA PARA CONVERTIR EL CONTADOR EN SU VALOR ASCII
;		Y PRESENTARLO EN LA LCD.
;	ENTRADAS:	NINGUNA
;	SALIDAS:	NINGUNA
;**************************************************************************************************
MUESTRA_CONTADOR
		MOVLW 	linea2LCD+5    ;Posiciona cursor en la 5 columna del segundo renglon de la LCD
	    	CALL	comandoLCD
		MOVF	C_MILLAR,W	;Prepara el contenido de las centenas de millar del contador
		CALL	CONVIERTE_VALOR	;Convierte las centenas de millar del contador en ASCII y depliegalas en la LCD
		MOVF	D_MILLAR,W	;Prepara el contenido de las decenas de millar del contador
		CALL	CONVIERTE_VALOR	;Convierte las decenas de millar del contador en ASCII y despliegalas en la LCD
		MOVF	MILLARES,W	;Prepara el contenido de las unidades de millar del contador
		CALL	CONVIERTE_VALOR	;Convierte las unidades de millar del contador en ASCII y despliegalas en la LCD
		MOVF	CENTENAS,W	;Prepara el contenido de las centenas del contador
		CALL	CONVIERTE_VALOR	;Convierte las centenas del contador en ASCII y despliegalas en la LCD
		MOVF	DECENAS,W	;Prepara el contenido de las decenas del contador
		CALL	CONVIERTE_VALOR	;Convierte las decenas del contador en ASCII y despliegalas en la LCD
		MOVF  	UNIDADES,W	;Prepara el contenido de unidades del contador
		CALL	CONVIERTE_VALOR	;Convierte las unidades del contador en ASCII y despliegalas en la LCD
		RETURN
	
;*************************************************************************************************
;		SUBRUTINA PARA CONVERTIR UN DATO A SU EQUIVALENTE ASCII Y MOSTRARLO EN LA LCD
;		ENTRADAS:	W (Conteniendo el valor a convertir)
;		SALIDAS:	Ninguna
;*************************************************************************************************
CONVIERTE_VALOR            	
	    	MOVWF 	TEMP		;Asignalo a la variable temporal
	    	MOVLW 	30H		;Prepara el dato de conversion a ASCII
	    	ADDWF 	TEMP,W		;Convierte el dato a su valor ASCII
            	CALL  	caracterLCD  	;Despliega el dato en el display
		RETURN

;**************************************************************************************************
;		SUBRUTINA PARA GENERAR UN DELAY DE 250 MICROSEGUNDOS
;**************************************************************************************************
DELAY_250US	MOVLW	.81			;Carga valor para generar un delay de 250 us
		MOVWF	DELAY_LCD		;Asignalo a variable auxiliar
		NOP
		DECFSZ	DELAY_LCD,F		;żYa se cumplio el delay?
		GOTO	$-2			;No, continua hastat terminar el delay
		GOTO	$+1
		RETURN				;Si, termina delay

;**************************************************************************************************
;		SUBRUTINA PARA GENERAR UN DELAY DE 1 MILISEGUNDO
;**************************************************************************************************
DELAY_1MS	MOVLW	.4			;Carga valor para generar un delay de 1ms
		MOVWF	DELAY_LCD1		;Asignalo a variable auxiliar
LES		CALL	DELAY_250US		;Realiza un delay de 250 us
		DECFSZ	DELAY_LCD1,F		;Ya se cumplio el delay?
		GOTO	LES
		RETURN				;Si, termina delay

;**************************************************************************************************
;		SUBRTUINA PARA GENERAR UN DELAY DE 50 MILISEGUNDOS
;**************************************************************************************************
DELAY_50MS	MOVLW	.200
		MOVWF	DELAY_LCD1		;Asignalo a variable auxiliar
MUCHOS		CALL	DELAY_250US		;Realiza un delay de 250 microsegundos
		DECFSZ	DELAY_LCD1,F		;Ya se cumplio el delay?
		GOTO	MUCHOS
		RETURN				;Si, termina delay.

;**************************************************************************************************
;		SUBRTUINA PARA GENERAR UN DELAY DE 500 MILISEGUNDOS
;**************************************************************************************************
DELAY_500MS	MOVLW	.10
		MOVWF	DELAY_LCD2		;Asignalo a variable auxiliar
MUCHOS1		CALL	DELAY_50MS		;Realiza un delay de 50 milisegundos
		DECFSZ	DELAY_LCD2,F		;Ya se cumplio el delay?
		GOTO	MUCHOS1
		RETURN				;Si, termina delay.
  
end

