;
;					EJEMPLO 2.19
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para simulación y/o MicroPIC Trainer
;
;La memoria EEPROM de datos.La máquina "SU TURNO"
;
;Se trata de emular el funcionamiento de las máquinas tipo "SU TURNO" habituales en múltiples
;comercios. Sobre el display se visualizará el número del turno actual. Este se icrementa a
;cada pulso aplicado por RA0. En la memoria EEPROM del PIC16F84 se almacena el último número
;visualizado, de forma que, ante un fallo de alimentación (p.e.), se reanude la cuenta en el
;último número.
;
;Si se parte de que el sistema se emplea por vez primera , se visualiza el 0

		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos
                    		
Contador	equ	0x0c		;Variable para el contador

		org	0x00		;Vector de Reset
		goto	Inicio
		org	0x05		;Salva vector de interrupción

;****************************************************************************************
;EE_Write: Graba un byte en la EEPROM de datos. La dirección será la contenida en EEADR y
;el dato se le supone previamente metido en EEDATA

EE_Write        bsf     STATUS,RP0	;Selecciona banco 1
                bsf     EECON1,WREN	;Permiso de escritura
                movlw   b'01010101'
                movwf   EECON2
                movlw   b'10101010'
                movwf   EECON2		;Secuencia establecida por Microchip
                bsf     EECON1,WR	;Orden de escritura
                bcf     EECON1,WREN	;Desconecta permiso de escritura
Wait            btfss   EECON1,EEIF	;Testear flag de fin de escritura
                goto    Wait
                bcf     EECON1,EEIF	;Reponer flag de fin de escritura
                bcf     STATUS,RP0	;Selección banco 0
                return

;**************************************************************************************
;EE_Read: Leer un byte de la EEPROM. Se supone al registro EEADR cargado con la direc-
;ción a leer. En EEDATA aparecerá el dato leído.

EE_Read         bsf     STATUS,RP0	;Selección de banco 1
                bsf     EECON1,RD	;Orden de lectura
                bcf     STATUS,RP0	;Selección de banco 0
                return

;**********************************************************************************
;Tabla: Esta rutina convierte el código BCD presente en los 4 bits de menos peso
;del reg. W en su equivalente a 7 segmentos. El código 7 segmentos retorna también
;en el reg. W

Tabla:		addwf	PCL,F			;Desplazamiento sobre la tabla
		retlw	b'00111111'		;Dígito 0
		retlw	b'00000110'		;Dígito 1
		retlw	b'01011011'		;Dígito 2
		retlw	b'01001111'		;Dígito 3
		retlw	b'01100110'		;Dígito 4
		retlw	b'01101101'		;Dígito 5
		retlw	b'01111101'		;Dígito 6
		retlw	b'00000111'		;Dígito 7
		retlw	b'01111111'		;Dígito 8
		retlw	b'01100111'		;Dígito 9

;*********************************************************************************
;Delay_20_ms: Esta rutina de temporización tiene por objeto eleiminar el "efecto
;rebote" de los periféricos electromecánicos. Realiza un delay de 20 mS. Si el PIC
;trabaja a una frecuencia de 4MHz, el TMR0 evoluciona cada uS. Si queremos tempori-
;zar 20000 uS (20 mS) con un preescaler de 128, el TMR0 deberá contar 156 eventos
;(156 * 128). El valor 156 equivale a 9c hex. y como el TMR0 es ascedente habrá que
;cargar su complemento a 1 (63 hex.).

Delay_20_ms:	bcf	INTCON,T0IF	;Desconecta el flag de rebosamiento
		movlw	0x63		;Complemento hex. de 156
		movwf	TMR0		;carga el TMR0
Delay_20_ms_1	clrwdt			;Refrescar el WDT
		btfss	INTCON,T0IF	;Rebasamiento del TMR0 ??
		goto	Delay_20_ms_1	;Todavía no
		bcf	INTCON,T0IF	;Ahora si, reponer el flag
		return


Inicio	        clrf 	PORTB		;Borra los latch de salida
		bsf	STATUS,RP0	;Selecciona banco 1
		clrf	TRISB		;Puerta B se configura como salida
		movlw	b'00011111'		
		movwf	TRISA		;Puerta A se configura como entrada		
		movlw	b'00000110'
		movwf	OPTION_REG	;Preescaler de 128 para el TMR0
		bcf	STATUS,RP0	;Selecciona banco 0			                                                                         					

		clrf	EEADR		;Selecciona dirección 00 de EEPROM				
		call	EE_Read		;Lee byte de la EEPROM
		movlw	0x09
		subwf	EEDATA,W
		btfsc	STATUS,C	;Mayor de 9 ??		
		goto	Ini_0		;Si, poner a 0 el contador
		goto	Ini_1		;No
Ini_0		clrf	Contador	;Poner a 0 el contador
		goto	Loop
Ini_1		movf	EEDATA,W
		movwf	Contador	;Iniciar contador

Loop		movf	Contador,W
		call	Tabla		;Convierte contador a 7 segmentos
		movwf	PORTB		;Visualiza sobre el display
		
Wait_0		clrwdt			;Refresca el WDT
		btfss	PORTA,0		;RA0 está a "1" ??
		goto	Wait_0		;No, esperar
		call	Delay_20_ms	;Eliminar rebotes

Wait_1		clrwdt			;Refrescar el WDT
		btfsc	PORTA,0		;RA0 está a "0" ??
		goto	Wait_1		;No, esperar
		call	Delay_20_ms	;Eliminar rebotes. Ha habido un pulso

		incf	Contador,F	;Incrementa contador
		movlw	.10
		subwf	Contador,W
		btfsc	STATUS,Z	;Contador mayor de 9 ??
		clrf	Contador	;Si, vuelta a 00
		movf	Contador,W
		movwf	EEDATA
		call	EE_Write	;Graba el nuevo valor del contador en la EEPROM
		goto	Loop

		end			;Fin del programa fuente

