;
;					ESEMPIO 2.16
;
;				Autore: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Generazione di numeri aleatori
;
;Ogni volta che si applica un impulso attraverso RA0, si genera un numero binario aleatorio di 8 bits 
;che verrà visualizzato sugli 8 leds connessi nella porta B, per 3 secondi.
;
;Tra le differenti tecniche, quella utilizzata per ottenere il numero, consiste nel catturare 
;il valore del TMR0 in un determinato momento.
	
		List	p=16F84		;Tipo di processore
		include	"P16F84.INC"	;Definizioni di registri interni
                    
Numero		equ	0x0c		;Numero aleatorio
Delay_Cont	equ	0x0d		;Contatore di intervalli
		
		org	0x00		;Vettore di Reset
		goto	Inizio
		org	0x05		;Salva vettore di interrupt
		
;*********************************************************************************
;Delay_20_ms: Questa procedura di temporizzazione ha per scopo di eliminare l'"effetto
;rimbalzo" delle periferiche elettromeccaniche. Realizza un delay di 20 mS. Se il PIC
;lavora a una frequenza di 4MHz, il TMR0 cambia ogni uS. Se vogliamo tempori-
;zzare 20000 uS (20 mS) con un prescaler di 256, il TMR0 dovrà contare 78 eventi
;(78 * 256). Il valore 78 equivale a 0x4e hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (0xb1 hex.).

Delay_20_ms:	bcf	INTCON,T0IF	;Disconnetti il flag di overflow
		movlw	0xb1		;Complemento hex. de 78
		movwf	TMR0		;carica il TMR0
Delay_20_ms_1	clrwdt			;Aggiornare il WDT
		btfss	INTCON,T0IF	;Overflow del TMR0 ??
		goto	Delay_20_ms_1	;Ancora no
		return

					
;*********************************************************************************
;Delay_var: Questa procedura a scopo generico realizza una temporizzazione variabile
;tra 50 mS e 12.8". Si impiega un prescaler di 256 e il TMR0 viene caricato con 195. 
;La velocità di lavoro è di 4Mhz e quindi il TMR0 incrementa ogni uS. In 
;questo modo, il TMR0 deve contare 195 eventi che, con un preescaler di 128 fa un
;intervallo totale di 50000 uS/50 mS (195 * 256). Il valore 195 va espresso
;in Hex. (c3) e poiché il TMR0 è ascendente bisognerà caricare il suo complemento (3C hex.)
;Tale intervallo di 50 mS si ripete tante volte quante ne indica la variabile "Delay_cont",
;è per questo che il delay minimo è di 50 mS ("Delay_cont=1) e il massimo di 12.8" 
;(Delay_cont=255).

Delay_var:	bcf	INTCON,T0IF	;Disconnetti il flag di overflow
		movlw	0x3c		;Complemento hex. de 195
		movwf	TMR0		;carica il TMR0
Intervallo	clrwdt			;Aggiornare il WDT
		btfss	INTCON,T0IF	;Overflow del TMR0 ??
		goto	Intervallo	;Ancora no		
		decfsz	Delay_Cont,F	;Diminusci contatore di intervalli
		goto	Delay_var	;Ripeti l'intervallo di 50 mS
		return	

Inizio	        clrf 	PORTB		;Cancella i latch di uscita
		bsf	STATUS,RP0	;Seleziona banco 1
		clrf	TRISB		;Porta B si configura come uscita
		movlw	b'00011111'		
		movwf	TRISA		;Porta A si configura come entrata		
		movlw	b'00000111'
		movwf	OPTION_REG	;Prescaler di 256 per il TMR0
		bcf	STATUS,RP0	;Seleziona banco 0			                                                                         					

Loop		clrwdt			;Aggiornare il WDT		
		btfss	PORTA,0		;Attivato RA0 ??
		goto	Loop		;Ancora No
		movf	TMR0,W		;Adesso sì.
		movwf	Numero		;Cattura il valore del TMR0 (Nº aleatorio)		
		call	Delay_20_ms	;Elimina rimbalzi		
			
RA0_1		clrwdt			;Aggiorna il WDT
		btfsc	PORTA,0		;Disattivato RA0 ??
		goto	RA0_1		;Ancora no	
		movf	Numero,W	;E' stato prodotto un impulso in RA0, si legge
		movwf	PORTB		;il valore catturato del TMR0 (Nº aleatorio)
					;e si toglie con i leds della PORTA B

		movlw	d'60'
		movwf	Delay_Cont	;Introduci variabile di temporizzazione
		call	Delay_var	;Temporizza 3 secondi
		clrf	PORTB		;Disconetti le uscite		
		goto 	Loop

		end			;Fine del programma principale

