;
;					ESEMPIO 2.15
;
;				Autore: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;Generazione di onde quadrate di differenti frequenze variando il valore del TMR0
;
;La linea di uscita RB0 cambierà stato a una frequenza determinata dal valore 
;introdotto mediante i 3 interruttori RA0-RA2:
;
;RA2	RA1	RA0	Frequenza	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
;
;Nel trattamento di interrupt che provocherà l'overflow del TMR0, si può
;notare come vengono salvati il W e il registro di stato, per recuperarli posteriormente.
;E' ciò che si chiama "salvare il contesto"
;
	
		List	p=16F84		;Tipo di processore
		include	"P16F84.INC"	;Definizioni di registri interni
                    
Valore		equ	0x0c	;Variabile di frequenza
W_Temp		equ	0x0d		;W temporale
Status_Temp	equ	0x0e		;Registro di stato temporale
		
		org	0x00		;Vettore di Reset
		goto	Inizio
		org	0x04		;Vettore di interrupt
		goto	Interrupt

;*********************************************************************************
;Tabella: questa procedura restituisce il valore da caricare nel TMR0 secondo la frequenza selez-
;ionata. Partendo da una frequenza generale di 4 MHz, il TMR0 cambia ogni 1 uS.
;Si seleziona un preescaler di 4. Il valore da caricare in TMR0 si ottiene dividendo il 
;semiperiodo della frequenza desiderata con il prescaler. Al valore ottenuto si
;sottrae 2 per motivi di sincronismo interno del PIC, si converte in hex. e si comple-
;menta.

Tabel.:		addwf	PCL,F		;Calcola spostamento della tabella
		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


Interrupt	movwf	W_Temp			;Salva il W
		swapf	STATUS,W
		movwf	Status_Temp	;Salva il registro di stato

		movf	Valore,W
		movwf	TMR0		;Ricarica il TMR0
		bcf	INTCON,T0IF	;Disattiva il flag TMR0		
		movlw	b'00000001'
		xorwf	PORTB,F		;Fai oscillare RB0
		
		swapf	Status_Temp,W
		movwf	STATUS		;Recupera il registro di stato
		swapf	W_Temp,F
		swapf	W_Temp,W	;Recupera il registro W

		retfie

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'00000001'
		movwf	OPTION_REG	;Prescaler di 4 per il TMR0
		bcf	STATUS,RP0	;Seleziona banco 0			                                                                         
		movlw	b'00100000'
		movwf	INTCON		;Interrupt TMR0 abilitato				

Loop		clrwdt			;Aggiornare il WDT		
		movf	PORTA,W
		andlw	b'00000111'
		btfss	STATUS,Z	;RA0-RA2 = 0 ??
		goto	Uscita_On	;No, uscita di frequenza
		bcf	INTCON,GIE	;Sì, interrupt OFF, frequenza OFF
		goto	Loop

Uscita_On	call	Tabella	;Determina valore da caricare in TMR0	
		movwf	Valor		;Carica la variabile
		bsf	INTCON,GIE	;Interrupt ON
		goto	Loop

		end			;Fine del programma principale

