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
|