;
;					EJEMPLO 2.16
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo para simulación y/o MicroPIC Trainer
;
;Generación de números aleatorios
;
;Cada vez que se aplique un pulso por RA0, se genera un número binario de 8 bits aleatorio
;que será visualizado sobre los 8 leds conectados en la puerta B, durante 3 segundos.
;
;Entre las diferentes ténicas, la empleada para obtener el número, consiste en capturar 
;el valor del TMR0 en un momento dado.
	
		List	p=16F84		;Tipo de procesador
		include	"P16F84.INC"	;Definiciones de registros internos
                    
Numero		equ	0x0c		;Número aleatorio
Delay_Cont	equ	0x0d		;Contador de intervalos
		
		org	0x00		;Vector de Reset
		goto	Inicio
		org	0x05		;Salva vector de interrupción
		
;*********************************************************************************
;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 256, el TMR0 deberá contar 78 eventos
;(78 * 256). El valor 78 equivale a 0x4e hex. y como el TMR0 es ascedente habrá que
;cargar su complemento a 1 (0xb1 hex.).

Delay_20_ms:	bcf	INTCON,T0IF	;Desconecta el flag de rebosamiento
		movlw	0xb1		;Complemento hex. de 78
		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
		return

					
;*********************************************************************************
;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 128 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	

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'00000111'
		movwf	OPTION_REG	;Preescaler de 256 para el TMR0
		bcf	STATUS,RP0	;Selecciona banco 0			                                                                         					

Loop		clrwdt			;Refrescar el WDT		
		btfss	PORTA,0		;Activado RA0 ??
		goto	Loop		;Todavía No
		movf	TMR0,W		;Ahora si.
		movwf	Numero		;Captura el valor del TMR0 (Nº aleatorio)		
		call	Delay_20_ms	;Elimina rebotes
					
RA0_1		clrwdt			;Refresca el WDT
		btfsc	PORTA,0		;Desactivado RA0 ??
		goto	RA0_1		;Todavía no	
		movf	Numero,W	;Se ha producido un impulso en RA0, se lee
		movwf	PORTB		;el valor capturado del TMR0 (Nº aleatorio)
					;y se saca por los leds de la PUERTA B

		movlw	d'60'
		movwf	Delay_Cont	;Inicia variable de temporización
		call	Delay_var	;Temporiza 3 segundos
		clrf	PORTB		;Desconecta las salidas		
		goto 	Loop

		end			;Fin del programa fuente

