;
;					EJEMPLO 3.5
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para MicroPIC Trainer y Trainer PLUS
;
;Wake-Up (despertar) del modo SLEEP mediante interrupción RB0.
;
;La interrupción se produce con el flanco descendente de RB0. RB0 está conectada, mediante
;la tecla 1, con RB4. A RB4 se le configura como salida a nivel "0". RB0 se configura como
;entrada con carga Pull-UP. Si la tecla está sin pulsar (abierta), RB0 permanecerá a "1". 
;Cuando se pulsa la tecla RB0 pasará a "0" provocándose la interrupción que finalizará el
;modo SLEEP de bajo consumo.
;
;El programa de tratamiento de la interrupción provoca el encendido del led conectado a RB7
;durante 1 segundo para luego desconectarlo y voler al modo SLEEP.
;
;Se recomienda poner el WDT en OFF para que no sea él quien provoque el Wake-Up y desconec-
;tar el LCD mediante el jumper J6 para que no interfiera con la línea RB0.

		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos
                 
Key_var		equ	0x0c		;Inicio de las variables del teclado				
Delay_Cont	equ	0x12		;Variable de temporización
					
		org	0x00		;Vector de reset
		goto	Inicio
		org	0x04		;Vector de interrupción
		goto	Interrupcion		
					
		include	"TECLADO.INC"	;Incluir rutinas de manejo del teclado
							
;*********************************************************************************
;Delay_var: Esta rutina de propósito general realiza una temporización variable
;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195. 
;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De 
;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una
;intervalo total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo
;en Hex. (c3) y como el TMR0 es ascendente habrá que cargar su complemento (3C hex.)
;Dicho intervalo de 50 mS se repite tantes veces como indique la variable "Delay_cont",
;es por ello que el delay mínimo es de 50 mS ("Delay_cont=1) y el máxima de 12.8" 
;(Delay_cont=255).

Delay_var:	bcf	INTCON,T0IF	;Desconecta el flag de rebosamiento
		movlw	0x3c		;Complemento hex. de 195
		movwf	TMR0		;carga el TMR0
Intervalo	clrwdt			;Refrescar el WDT
		btfss	INTCON,T0IF	;Rebasamiento del TMR0 ??
		goto	Intervalo	;Todavía no		
		decfsz	Delay_Cont,F	;Decrementa contador de intervalos
		goto	Delay_var	;Repite el intervalo de 50 mS
		return	

;****************************************************************************************
;Tratamiento de la interrupción que se provoca cada vez que en RB0 se detecta un flanco
;ascendente como consecuencia de haber pulsado la tecla 1

Interrupcion:	bcf	INTCON,INTF	;Desactiva flag INTF
		bsf	PORTB,7		;Activa la salida RB7
		movlw	.20
		movwf	Delay_Cont
		call	Delay_var	;Temporiza 1 segundo
		bcf	PORTB,7		;Desactiva RB7
Es_0		btfss	PORTB,0		;Espera que RB0 pase a "1" (tecla abierta)
		goto	Es_0
		retfie			;Fin de interrupción

;****************************************************************************************
;Programa Principal

Inicio:		clrf	PORTB		;Borra salidas
		bsf	STATUS,RP0	;Selecciona página 1 de datos
		movlw	b'00000111'	;Cargas Pull-Up activadas,RB0 sensible al descendente
		movwf	OPTION_REG	;y el preescalr de 256 asignado al WDT
		movlw	b'00001111'
		movwf	TRISB		;RB7-RB4 salidas, RB3-RB0 entradas
		bcf	STATUS,RP0	;Selecciona página 0 de datos	
		movlw	b'10010000'
		movwf	INTCON		;Activa interrupción RB0
		
Loop		sleep			;Puesta en standby de bajo consumo
		nop			;Wake-Up
		goto	Loop
			
		end			;Fin del programa fuente

