;
;					EJEMPLO 2.15
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para simulación y/o MicroPIC Trainer
;
;Generación de ondas cuadradas de diferentes frecuencias variando el valor del TMR0
;
;La línea de salida RB0 cambiará de estado a una frecuencia determinada por el valor 
;introducido mediante los 3 interruptores RA0-RA2:
;
;RA2	RA1	RA0	Frecuencia	Periodo		Semiperiodo
;---	---	---	----------	-------		-----------
;0	0	0	0 KHz		---		---
;0	0	1	1 KHz		1000 uS		500 uS
;0	1	0	2 KHz		500 uS		250 uS
;0	1	1	3 KHz		333 uS		166 uS
;1	0	0	4 KHz		250 uS		125 uS
;1	0	1	5 KHz		200 uS		100 uS
;1	1	0	6 KHz		166 uS		83 uS
;1	1	1	7 KHz		143 uS		71 uS
;
;En el tratamiento de interrupción que provocará el desbordamiento del TMR0, se puede
;apreciar como se salva el W y el registro de estado, para recuperarlos posteriormente.
;Es lo que se llama "salvar el contexto"
;
	
		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos
                    
Valor		equ	0x0c		;Variable de frecuencia
W_Temp		equ	0x0d		;W temporal
Status_Temp	equ	0x0e		;Registro de estado temporal
		
		org	0x00		;Vector de Reset
		goto	Inicio
		org	0x04		;Vector de interrupción
		goto	Interrupcion

;*********************************************************************************
;Tabla: esta rutina devuelve el valor a cargar en el TMR0 según la frecuencia selec-
;cionada. Partiendo de una frecuencia general de 4 MHz, el TMR0 evoluciona cada 1 uS.
;Se selecciona una preescaler de 4. El valor a cargar en TMR0 se obtiene de dividir el 
;semiperiodo de la frecuencia deseada entre el preescaler. Al valor obtenido se le
;resta 2 por motivos de sincronismo interno del PIC, se convierte a hex. y se comple-
;menta.

Tabla:		addwf	PCL,F		;Calcula desplazamiento de la tabla
		retlw	0x00		;0 KHz
		retlw	0x86		;1 KHz
		retlw	0xc5		;2 KHz
		retlw	0xda		;3 KHz
		retlw	0xe4		;4 KHz
		retlw	0xea		;5 KHz
		retlw	0xee		;6 KHz
		retlw	0xf1		;7 KHz


Interrupcion	movwf	W_Temp		;Salva el W
		swapf	STATUS,W
		movwf	Status_Temp	;Salva el registro de estado

		movf	Valor,W
		movwf	TMR0		;Recarga el TMR0
		bcf	INTCON,T0IF	;Desactiva el flag TMR0		
		movlw	b'00000001'
		xorwf	PORTB,F		;Bascula RB0
		
		swapf	Status_Temp,W
		movwf	STATUS		;Recupera el registro de estado
		swapf	W_Temp,F
		swapf	W_Temp,W	;Recupera el registro W

		retfie

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'00000001'
		movwf	OPTION_REG	;Preescaler de 4 para el TMR0
		bcf	STATUS,RP0	;Selecciona banco 0			                                                                         
		movlw	b'00100000'
		movwf	INTCON		;Interrupción TMR0 habilitada				

Loop		clrwdt			;Refrescar el WDT		
		movf	PORTA,W
		andlw	b'00000111'
		btfss	STATUS,Z	;RA0-RA2 = 0 ??
		goto	Salida_On	;No, salida de frecuencia
		bcf	INTCON,GIE	;Si, interrupciones OFF, frecuencia OFF
		goto	Loop

Salida_On	call	Tabla		;Determina valor a cargar en TMR0	
		movwf	Valor		;Carga la variable
		bsf	INTCON,GIE	;Interrupciones ON
		goto	Loop

		end			;Fin del programa fuente

