;
;					ESEMPIO 2.19
;
;				Autore: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Esempio per simulazione e/o MicroPIC Trainer
;
;La memoria EEPROM di dati.La macchina "SUO TURNO"
;
;Si tratta di simulare il funzionamento delle macchine tipo "SUO TURNO" comuni in molteplici
;attività. Sul display verrà visualizzato il numero del turno attuale. Questo aumenta a
;ogni impulso applicato da RA0. Nella memoria EEPROM del PIC16F84 si immagazzina l'ultimo numero
;visualizzato, in modo che, davanti a una mancanza di alimentazione (p.e.), si riprenda il conto dall'
;ultimo numero.
;
;Se si inizia utilizzando il sistema per la prima volta , si visualizza lo 0

		List	p=16F84		;Tipo di processore
		include	"P16F84.INC"	;Definizioni di registri interni
                    		
Contatore	equ	0x0c		;Variabile per il contatore

		org	0x00		;Vettore di Reset
		goto	Inizio
		org	0x05		;Salva vettore di interrupt

;****************************************************************************************
;EE_Write: Registra un byte nella EEPROM di dati. L'indirizzo sarà quello contenuto in EEADR e
;il dato si suppone sia stato precedentemente messo in EEDATA

EE_Write        bsf     STATUS,RP0	;Seleziona banco 1
                bsf     EECON1,WREN	;Permesso di scrittura
                movlw   b'01010101'
                movwf   EECON2
                movlw   b'10101010'
                movwf   EECON2		;Sequenza stabilita da Microchip
                bsf     EECON1,WR	;Ordine di scrittura
                bcf     EECON1,WREN	;Disconnetti permesso di scrittura
Wait            btfss   EECON1,EEIF	;Controllare flag di fine di scrittura
                goto    Wait
                bcf     EECON1,EEIF	;Rimettere flag di fine di scrittura
                bcf     STATUS,RP0	;Selezione banco 0
                return

;**************************************************************************************
;EE_Read: Leggere un byte dalla EEPROM. Il registro EEADR deve essere caricato con l'indiriz-
;zo da leggere. In EEDATA apparirà il dato letto.

EE_Read         bsf     STATUS,RP0	;Selezione di banco 1
                bsf     EECON1,RD	;Ordine di lettura
                bcf     STATUS,RP0	;Selezione di banco 0
                return

;**********************************************************************************
;Tabella: Questa procedura converte il codice BCD presente nei 4 bits di minor peso
;del reg. W nel suo equivalente a 7 segmenti. Il codice a 7 segmenti ritorna anche
;nel reg. W

Tabella:		addwf	PCL,F			;Spostamento sulla tabella
		retlw	b'00111111'		;Cifra 0
		retlw	b'00000110'		;Cifra 1
		retlw	b'01011011'		;Cifra 2
		retlw	b'01001111'		;Cifra 3
		retlw	b'01100110'		;Cifra 4
		retlw	b'01101101'		;Cifra 5
		retlw	b'01111101'		;Cifra 6
		retlw	b'00000111'		;Cifra 7
		retlw	b'01111111'		;Cifra 8
		retlw	b'01100111'		;Cifra 9

;*********************************************************************************
;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 128, il TMR0 dovrà contare 156 eventi
;(156 * 128). Il valore 156 equivale a 9c hex. e poiché il TMR0 è ascendente bisognerà
;caricare il suo complemento a 1 (63 hex.).

Delay_20_ms:	bcf	INTCON,T0IF	;Disconnetti il flag di overflow
		movlw	0x63		;Complemento hex. de 156
		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
		bcf	INTCON,T0IF	;Adesso sì, rimettere il flag
		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'00000110'
		movwf	OPTION_REG	;Prescaler di 128 per il TMR0
		bcf	STATUS,RP0	;Seleziona banco 0			                                                                         					

		clrf	EEADR		;Seleziona indirizzo 00 di EEPROM				
		call	EE_Read		;Leggi byte dalla EEPROM
		movlw	0x09
		subwf	EEDATA,W
		btfsc	STATUS,C	;Maggiore di 9 ??		
		goto	Ini_0		;Sì, mettere a 0 il contatore
		goto	Ini_1		;No
Ini_0		clrf	Contatore	;Mettere a 0 il contatore
		goto	Loop
Ini_1		movf	EEDATA,W
		movwf	Contatore	;Avviare contatore

Loop		movf	Contatore,W
		call	Tabella		;Converti contatore a 7 segmenti
		movwf	PORTB		;Visualizza sul display
		
Wait_0		clrwdt			;Aggiorna il WDT
		btfss	PORTA,0		;RA0 è a "1" ??
		goto	Wait_0		;No, aspettare
		call	Delay_20_ms	;Eliminare rimbalzi

Wait_1		clrwdt			;Aggiornare il WDT
		btfsc	PORTA,0		;RA0 è a "0" ??
		goto	Wait_1		;No, aspettare
		call	Delay_20_ms	;Eliminare rimbalzi. C'è stata un impulso

		incf	Contatore,F	;Aumenta contatore
		movlw	.10
		subwf	Contatore,W
		btfsc	STATUS,Z	;Contatore maggiore di 9 ??
		clrf	Contatore	;Sì, ritorno a 00
		movf	Contatore,W
		movwf	EEDATA
		call	EE_Write	;Registra il nuovo valore del contatore nella EEPROM
		goto	Loop

		end			;Fine del programma principale

