Espanol
AddThis Social Bookmark Button

19 Input/Output

Come già visto, possiamo usare i registri PORTA e PORTB per modificare lo stato
dei pin o per leggerne il valore; prima, però, bisogna definire quali sono gli ingressi
e le uscite, dobbiamo quindi modificare i registri TRISA e TRISB.
Quest'ultimi si trovano nel banco 1 e per accedervi agiremo sul registro di STATUS:

	bsf	STATUS,RP0	; mette a uno il bit RP0, viene selezionato il banco 1

A questo punto è possibilie modificare i due registri: metteremo le due porte tutte
come ingresso, tranne il primo piedino della porta B.

	movlw	B'11111111'
	movwf	TRISA
	movlw	B'11111110'
	movwf	TRISB

Quindi si torna al banco 0:

	bcf	STATUS,RP0	; mette a zero il bit RP0, viene selezionato il banco 0

Ora, agendo sul primo bit di PORTB, con le istruzioni bsf e bcf, cambierà lo stato dell'uscita:

	bsf	PORTB,0		; il pin RB0 è a 5V
	bcf	PORTB,0		; il pin RB0 è a 0V

Esempio pratico
Come primo esempio pratico, realizziamo il programma che fa lampeggiare un LED.
Il codice sorgente completo è disponibile qui, ma vediamolo in dettaglio:
la testata del programma e la configurazione delle porte è già stata illustrata,
quindi esaminiamo il resto del programma.

Main
	bsf	PORTB,0		; LED acceso
	call	Delay

	bcf	PORTB,0		; LED spento
	call	Delay

	goto	Main		; torna a Main

Questo è il corpo principale del programma: è costituito da un ciclo infinito:
una volta eseguite le quattro istruzioni, attraverso il goto, ritorna all'inizio e così via in eterno.
Come suggeriscono i commenti, le due istruzioni bsf e bcf accendono e spengono alternativamente il LED,
ma essendo la frequenza di lavoro molto elevata, ai nostri occhi il LED sembrerebbe sempre acceso;
per questo motivo è stata introdotta una routine di ritardo, chiamata Delay.

Si fa uso dell'istruzione call perchè, una volta eseguito il ritardo, si ritorna al corpo principale
del programma.

Vediamo dunque come viene fatto questo ritardo:

Delay
	clrf	Count1		; azzera i contatori
	clrf	Count2		;
Loop
	decfsz	Count2,F
	goto	Loop

	decfsz	Count1,F
	goto	Loop

	return			; ritorna al programma principale

Si tratta di due iterazioni a cicli fissi (viste nella lezione precedente) innestate una nell'altra; azzerando i contantori si ottiene
il numero massimo di iterazioni, ovvero 256 ciascuno, per un totale di 256*256 = 65536 cicli.

Il blocco di istruzioni:

	decfsz	Count2,F
	goto	Loop

decrementa Count2 per 256 volte, finchè non raggiunge lo zero: a questo punto si passa al secondo blocco
che decrementa il registro Count1 una volta, per poi tornare a "Loop" dove il registro Count2 verrà nuovamente
decrementato per 256 volte. Infine quando anche il Count1 raggiunge lo zero, la routine finisce con l'istruzione return.

Mettendo a zero i contatori non si ottiene il minor numero di iterazioni come si potrebbe
pensare bensì il massimo, infatti l'istruzione decfsz prima decrementa e solo poi esegue il controllo sullo zero,
perciò al primo decremento il contatore varrà 255, saranno quindi 256 le iterazioni totali.
Sappiamo che con un clock a 4Mhz, un ciclo istruzione è di un microsecondo,
perciò è possibile calcolare l'entità del ritardo:
- 2 per la call
- 1 per clrf
- 1 per decfsz
- 2 per goto, tranne quando viene fatto saltare da decfsz
- 2 per il return
quindi : 2 + 2 + ((3*256 - 1) + 3)*256 - 1 + 2  = 200ms circa