;===============================================================================================================================================

; 					CODIGO FUENTE PARA LA TARJETA EVOLUPIC 16F88 USANDO EL MÓDULO DE EXPANSIÓN DE 7 SEGMENTOS
;		             AUTOR: MOISES RAFAEL GUTIERREZ DAMIAN, PROGRAMA DESARROLLADO PARA PUNTO FLOTANTE, S.A.

;===============================================================================================================================================

;		EL PROGRAMA REALIZA UNA CUENTA DECIMAL DE 0 A 999 DETERMINANDO EL PERIODO DE LA CUENTA MEDIANTE LA INTERRUPCIÓN DE 
;												  DESBORDAMIENTO DEL TIMER 0

;===============================================================================================================================================

;	NOTAS SOBRE EL CÓDIGO FUENTE: ***************************************************************************************************************
 
;	RA1 SE USA PARA DAR RESET AL CONTADOR DE COLUMNAS
; 	RA2 SE USA PARA INCREMENTAR EL CONTADOR DE COLUMNAS
; 	EL PUERTO B ES USADO PARA ENCENDER LOS SEGMENTOS
 
;	CONFIGURACION: ******************************************************************************************************************************* 

	processor 16f88A
	include	  <p16f88.inc>
	


;	DATOS: **************************************************************************************************************************************

	#DEFINE BANCO0	BCF	STATUS,RP0
	#DEFINE	BANCO1	BSF	STATUS,RP0
	
	CBLOCK	0x22		; LAS VARIABLES SE GUARDAN A PARTIR DE ESTA DIRECCIÓN
	UNI					; UNIDADES
	DEC					; DECENAS
	CEN					; CENTENAS
	L					; USADO EN EL BARRIDO DE COLUMNAS
	REG50mS				; VARIABLE USADA COMO REGISTRO AUXILIAR PARA TRABAJAR EL TMR0
	SALVA_W				; UTILIZADAS DURANTE LA INTERRUPCIÓN PARA EVITAR SALTOS INDETERMINADOS
	SALVA_STATUS		;
	ACARREOS			; USADO COMO FLAGS EN LA CUENTA 
	ENDC				

J				EQU	H'20'	; USADOS PARA RETARDOS
K				EQU	H'21'	;

;**************************************************************************
;																		  *
CARGA			EQU	D'5'	; CARGA X 50 mS = PERIODO DE CUENTA DESEADO   *
;																		  *
;**************************************************************************

TMR0_50mS		EQU	D'61'	; INICIALIZACIÓN CALCULADA PARA DAR UN CICLO DE 50 mS (NO DEBE MODIFICARSE)		
	
;	CODIGOS: ***********************************************************************************************************************************
	ORG		0
	CLRF	PCLATH
	GOTO	INICIO
	

	ORG		4
	GOTO	INTERRUP		; VECTOR DE INTERRUPCION
	
INICIO
	BANCO0
	bcf		RCSTA,SPEN	;DESHABILITA UART
	BANCO1
	movlw	7
	movwf	CMCON
	clrf	CVRCON
	clrf	ANSEL	
	CLRF	TRISB			; PUERTO B SALIDAS
	CLRF	TRISA			; PUERTO A SALIDAS
	MOVLW	B'00000111'		; PRESCALER RATE SELECT BITS CONFIGURADOS PARA UN DIVISOR DE FREC 1:256 Y DESBORDAMIENTO POR RELOJ INTERNO
	MOVWF	OPTION_REG		; EN EL REGISTRO OPTION.
		
	BANCO0					; ACCESO AL BANCO 0
	CLRF	PORTA			; TODAS LAS SALIDAS EN ESTADO BAJO
	CLRF	PORTB			; 
	MOVLW	TMR0_50mS		; CARGA INICIAL DEL TIMER0
	MOVWF	TMR0			;
	MOVLW	CARGA			; CARGA DE LA VARIABLE REGISTRO
	MOVWF	REG50mS			;
	BSF		INTCON,GIE		; HABILITAMOS LAS INTERRUPCIONES
	BSF		INTCON,TMR0IE		; HABILITAMOS LA INTERRUPCIÓN POR DESBORDAMIENTO DEL TMR0

	;********************************************************************************
	;*   LAS DOS LINEAS ANTERIORES PUEDEN SER SUSTUIDAS POR LAS SIGUIENTES LINEAS:  *
	;*																			 	*
	;*	 MOVLW	B'10100000'															*
	;*	 MOVWF	INTCON																*
	;********************************************************************************
	
	CLRF	UNI
	CLRF	DEC
	CLRF	CEN
	CLRF	ACARREOS
	
BUCLE2		
	CLRF	L			; INICIALIZAMOS LA VARIABLE
	CALL	MR			; SALTO A SUBRUTINA MR

BUCLE1		
	MOVFW	L
	CALL	DIGITO
	MOVWF	PORTB
	CALL	CP0			; SALTO A SUBRUTINA CP0
	CALL 	RETRO
	INCF	L,F
	MOVFW	L
	SUBLW	3			; SON 3 COLUMNAS
	BTFSS	STATUS,Z
	GOTO	BUCLE1		; BUCLE INFINITO
CERO
	GOTO	BUCLE2

DIGITO
	ADDWF	PCL			; SALTO INDEXADO APROVECHANDO EL CONTADOR L USADO PARA EL BARRIDO DE COLUMNAS
	GOTO 	CENTENAS	
	GOTO	DECENAS
	GOTO	UNIDADES
	
CENTENAS
	MOVFW	CEN			; CARGA EN W EL VALOR DE LAS CENTENAS
	GOTO	INDEXADO	; SALTO A SUBRUINA INDEXADO
	RETURN	
DECENAS
	MOVFW	DEC			; CARGA EN W EL VALOR DE LAS DECENAS
	GOTO	INDEXADO	; SALTO A SUBRUINA INDEXADO
	RETURN	
UNIDADES
	MOVFW	UNI			; CARGA EN W EL VALOR DE LAS UNIDADES
	GOTO	INDEXADO	; SALTO A SUBRUINA INDEXADO
	RETURN
	
INDEXADO
	ADDWF	PCL			; USAMOS EL SALTO INDEXADO PARA ENCENDER LOS SEGMENTOS
	RETLW	B'01111110'	; 0
	RETLW	B'00001100'	; 1
	RETLW	B'10110110'	; 2
	RETLW	B'10011110'	; 3
	RETLW	B'11001100'	; 4
	RETLW	B'11011010'	; 5
	RETLW	B'11111010'	; 6
	RETLW	B'00001110'	; 7
	RETLW	B'11111110'	; 8
	RETLW	B'11001110'	; 9

MR						; MANDA PULSO AL PUERTO RA1
	BSF		PORTA,1		; MASTER RESET AL CONTADOR (FLANCO DE SUBIDA)
	CALL	UNMILI		; RETRASO DE 1 MILISEGUNDO
	BCF		PORTA,1		; FLANCO DE BAJADA
	RETURN				

CP0						; PULSO DE RELOJ POR EL PUERTO RA2
	BSF		PORTA,2		; INCREMENTA COLUMNA CONTADOR (FLANCO DE SUBIDA)
	CALL	UNMILI		; RETRASO DE 1 MILISEGUND0
	BCF		PORTA,2		; FLANCO DE BAJADA
	RETURN
	 
RETRO					
	movlw	D'35'		;RUTINA RETRASO 10 MS
	movwf	J			; J = w
jloop
	movwf	K			; K = w
kloop
	decfsz	K,f			; K = K-1, skip next if zero
	goto 	kloop
	decfsz	J,f			; J = J-1, skip next if zero
	goto	jloop
	return

UNMILI	
	movlw	D'250'		; RUTINA RETRASO 1 MILISEGUNDO
	movwf	K			; J = w
kloop2
	decfsz	K,f			; K = K-1, skip next if zero
	goto 	kloop2
	return

;	RUTINA DE ATGENCIÓN A LA INTERRUPCIÓN: ******************************************************************************************************

INTERRUP

;	SALVADO DE REGISTROS: ***********************************************************************************************************************
	
	MOVWF	SALVA_W			; GUARDAMOS EL REGISTRO W ANTES DE LA INTERRUPCIÓN
	SWAPF	STATUS,W		; USADO PARA GUARDAR EL REGISTRO STATUS, OTRA INSTRUCCIÓN AFECTA LOS BITS DE ESTADO
	MOVWF 	SALVA_STATUS	;

;	RUTINA DE TEMPORIZACIÓN LARGA: **************************************************************************************************************
	
	MOVLW	TMR0_50mS		; REINICIAMOS EL TIMER0
	MOVWF	TMR0
	DECFSZ	REG50mS,F		; DECREMENTAMOS EL CONTADOR AUXILIAR
	GOTO	TODAVIA_NO		; TODAVÍA NO SE ALCANZA EL TIEMPO DESEADO

;	RUTINA DEL CONTADOR: ***********************************************************************************************************************
	
							; YA SE CUMPLIÓ EL TIEMPO ESTABLECIDO
	BTFSC	ACARREOS,0		; VIENE DE ESCRIBIR EL NUMERO 9
	GOTO	UNID_9			; SI. REINICIA LAS UNIDADES
	INCF	UNI,F			; NO, ENTONCES SUMA 1
	MOVFW	UNI				; COMPARAMOS PARA SABER SI YA ALCANZAMOS EL NUMERO 9
	SUBLW	9				;
	BTFSS	STATUS,Z		; YA LLEGAMOS AL 9?
	GOTO	INTERRUP_FIN	; NO, SIGUE CON LA CUENTA NORMAL
	BSF		ACARREOS,0		; YA, ACTIVA EL FLAG.
	GOTO	INTERRUP_FIN
INC_DEC	
	BTFSC	ACARREOS,1		; VENIMOS DE ESCRIBIR X9X?
	GOTO	DEC_9			; SI, REINICIA EL CONTADOR.
	INCF	DEC,F			; NO, SIGUE CONTANDO
	MOVFW	DEC				; 
	SUBLW	9				;
	BTFSS	STATUS,Z		; YA LLEGAMOS AL X9X?
	GOTO	INTERRUP_FIN	; NO, SIGUE CONTANDO
	BSF		ACARREOS,1		; SI, ACTIVA EL FLAG PARA EL PROXIMO CICLO.
	GOTO	INTERRUP_FIN	
INC_CEN
	BTFSC	ACARREOS,2		; VENIMOS DEL 9XX?
	GOTO	CEN_9			; SI, REINCIA LAS CENTENAS
	INCF	CEN,F			; NO, SIGUE CONTANDO
	MOVFW	CEN				;
	SUBLW	9				;
	BTFSS	STATUS,Z		; LLEGAMOS AL 9XX?
	GOTO	INTERRUP_FIN	; NO, SIGUE LA CUENTA
	BSF		ACARREOS,2		; SI, REINICIA LAS CENTENAS
	GOTO	INTERRUP_FIN

UNID_9						; RUTINA DE REINICIO DE LAS UNIDADES
	CLRF	UNI				; XX0
	BCF		ACARREOS,0		; BORRA EL FLAG DE ACARREO
	GOTO	INC_DEC			; SIGUE CON LA CUENTA
DEC_9						; RUTINA DE REINICIO DE LAS DECENAS
	CLRF	DEC				; X0X	
	BCF		ACARREOS,1		; BORRA EL FLAG DE ACARREO
	GOTO	INC_CEN			; SIGUE CON LA CUENTA
CEN_9						; RUTINA DE REINICIO DE LAS CENTENAS
	CLRF	CEN				; OXX
	BCF		ACARREOS,2		; BORRA EL FLAG DE REINICIO

;	FIN DE LA RUTINA DE INTERRUPCIÓN: ***********************************************************************************************************
	
INTERRUP_FIN
	MOVLW	CARGA			; W = NUESTRA VARIABLE DE TIEMPO
	MOVWF	REG50mS			; COMIENZA EL NUMERO DE REPETICIONES NECESARIAS PARA EL TIEMPO REQUERIDO

;	RESTAURACIÓN DE REGISTROS: ******************************************************************************************************************

TODAVIA_NO					; RUTINA DE RESTAURACIÓN DE LOS REGISTROS
	SWAPF	SALVA_STATUS,W
	MOVWF	STATUS
	SWAPF	SALVA_W,F
	SWAPF	SALVA_W,W

;	FIN DE LA INTERRUPCIÓN: *********************************************************************************************************************

	BCF		INTCON,TMR0IF		; BORRA EL FLAG DE INTERRUPCIÓN
	RETFIE					; REGRESA DE LA INTERRUPCIÓN

;************************************************************************************************************************************************

	END						; FIN DEL PROGRAMA
	


