Utilizzare le porte di I/O


    Le porte di I/O (PORT A e PORT B)



Il PIC dispone di 13 linee di I/O, programmabili individualmente come linee di ingresso o uscita. Questi pin sono mappati direttamente nei registri PORT_A e PORT_B.
PORT_B controlla i pin RB0,RB1,RB2,RB3,RB4,RB5,RB6 e RB7.
PORT_A controlla i pin RA0,RA1,RA2,RA3 e RA4. I tre bit piu' significativi del registro non sono usati (si ricorda che la porta A possiede solo 5 linee)
In figura si mostrano i collegamenti logici* tra porte e pin di I/O esterni:
* ovviamente la struttura interna reale di "collegamento" e' molto piu' complessa




I due registri PORT_A e PORT_B hanno associati i relativi registri di direzione, cioe' TRIS_A e TRIS_B. Questi ultimi due registri sono posizionati nel banco 1 della RAM in corrispondenza dei primi. Ogni bit dei registri TRIS_A e TRIS_B specifica la direzione della relativa linea di I/O. Se il bit vale 1, la corrispondente linea e' di input, se vale 0 e' di output. Ovviamente anche il registro TRIS_A sara' di soli 5 bit; i 3 bit piu' significativi non sono utilizzati.
Di default (quindi anche all'accensione del pic) tutti i bit del registro TRIS_A e di TRIS_B sono impostati a 1; cio' significa che tutte le linee RA0...RA3 e RB0..RB7 sono di input.
Per modificare la direzione di una linea di I/O e' sufficiente settare opportunamente il bit corrispondente nel registro TRIS_A o TRIS_B, ad esempio utilizzando le istruzioni di set e clear dei bit oppure scrivendo direttamente il byte opportuno con MOVWF.




    Caratteristiche elettriche




Linee porta A

Le linee della porta A come detto prima sono 5, associate ai registri PORT_A e TRIS_A. I pin RA0,RA1,RA2 e RA3, quando configurati come output, sono di tipo push-pull, ovverosia possono essere utilizzati sia come "sorgenti" di corrente (drain mode) che come "pozzi" (sink mode), in altre parole sono in grado sia di assorbire corrente dal positivo dell'alimentazione (25mA max), sia di fornirla verso massa (20mA max).
In figura si mostrano i collegamenti interni per i pin RA0,RA1,RA2 e RA3:



Il pin RA4 e' un caso a parte perche' e' di tipo a collettore aperto (open drain); cio significa che e' possibile utilizzarlo esclusivamente come pozzo di corrente: il suo comportamento equivalente e' come quello di un interruttore che si chiude verso massa. La figura mostra i collegamenti interni relativi alla linea RA4:



I pin della porta A impostati come ingressi sono automaticamente configurati come linee in alta impedenza (flottanti); se una di tali linee non viene utilizzata occorre necessariamente collegarla al positivo (VCC) tramite apposita resistenza di pull-up (ad esempio da 10Kohm).


Linee porta B


La porta B e' composta da 8 linee, RB0,RB1,RB2,RB3,RB4,RB5,RB6 e RB7. Quando una linea B e' impostata come output, valgono le stesse considerazioni viste per le linee RA0,RA1,RA2 e RA3 (modalita' sink/drain e stessi assorbimenti massimi).
In modalita' input le linee B possiedono ognuna una resistenza di pull-up interna, non e' quindi necessario inserirla esternamente come accade per le linee A. Tali resistenze interne possono essere abilitate settando a zero il bit #RBPU del registro OPTION_REG (il registro e' collocato nel banco RAM 1, alla locazione 0x01). Di default le resistenze sono disabiltate.




    Lettura e scrittura



La lettura e scrittura delle porte di I/O e' estremamente semplice. Una volta che si siano scelte le direzioni delle linee tramite l'imposizione dei bit dei registri TRIS_A e TRIS_B sara' sufficiente settare opportunamente i bit dei registri di porta (ad esempio con le istruzioni MOV,BCF,BSF etc..) per ottenere le tensioni ai capi dei pin corrispondenti. Ovviamente ha senso imporre lo stato dei bit solo per le linee dichiarate come output. Per acquisire lo stato delle linee di input e' sufficiente andare a leggere lo stato dei relativi bit di porta, con le normali tecniche di lettura dei registri messe a disposizione (istruzioni della famiglia MOV).
Una linea di I/O impostata come output presentera' all'esterno (cioe' sul relativo pin) una tensione di +5volt se il bit corrispondente nel registro di porta (PORT_A o PORT_B) e' settato ad 1; 0volt nel caso sia settato a 0.
Una linea di I/O impostata come input invece e' l'esatto contrario: se la tensione ai capi del relativo pin e' di circa 5volt, allora il PIC imposta ad 1 il bit corrispondente nel registro di porta. Se la tensione e' nulla, lo setta a 0.



    Esempi software



Esempio:
Inizializzare la porta A in modo che RA0 e RA1 siano di output e RA2,RA3 e RA4 di input.

STATUS EQU 0x03
PORT_A EQU 0x05
TRIS_A EQU 0x05

BCF   STATUS,5          ;selezione del banco RAM 0
CLRF  PORT_A            ;azzeramento di PORT_A
BSF   STATUS,5          ;selezione del banco RAM 1
MOVLW 0x1C              ;valore di inizializzazione
MOVWF TRIS_A            ;scrittura del valore in TRIS_A

NOTA: 0x1C e' il valore di inizializzazione corretto perche' in binario vale 11100. Scrivere tale parola in TRIS_A corrisponde a dichiarare le prime due linee come output (RA0 e RA1) e le restanti tre (RA2 RA3 RA4) come input.


Esempio:
Supponendo che tutte le linee della porta B siano gia' settate come input, leggere tale porta e salvare il risultato alla locazione 0x20 (un registro GPR).

STATUS EQU 0x03

BCF   STATUS,5          ;selezione del banco RAM 0
MOVF  0x06,0            ;caricamento del contenuto di PORT_B in W
MOVWF 0x20              ;scrive il contenuto di W alla locazione 0x20


Esempio:
Supponendo che tutte le linee della porta B siano gia' settate come output, scrivere il contenuto del registro 0x20 su tale porta.

STATUS EQU 0x03
PORT_B EQU 0x06

BCF   STATUS,5          ;selezione del banco RAM 0
MOVF  0x20,0            ;caricamento del contenuto del registro 0x20 in W
MOVWF PORT_B            ;scrive il contenuto di W in PORT_B



    Esempi di collegamento


Utilizzare i piedini come output


Ecco alcuni esempi di collegamenti al pin RB0 configurato come output.
In figura si riporta un collegamento di un led alla linea RB0 del microcontrollore:



Pilotare un led con RB0 - source mode


La resistenza da 330 ohm limita la corrente nel ramo a circa 15mA. Quando sulla linea RB0 viene imposto un 1 il piedino si porta a VCC Volt ed inizia a fluire una corrente VERSO massa e quindi il led si accende. Quando viene imposto 0 il piedino si porta a massa e la corrente smette di fluire; il led si spenge.
Il circuito appena descritto utilizza il piedino RB0 come sorgente (source) di corrente.
Il prossimo schema mostra come utilizzare il piedono RB0 come pozzo (sink) di corrente:


Pioltare un led con RB0 - sink mode  


Quando sulla linea RB0 viene imposto un 1 il piedino si porta alla tensione VCC (esattamente come prima) ma il questa volta il led rimane spento perche non fluisce corrente. Quando viene imposto uno 0, il piedino si porta a massa ed inizia a scorrere una corrente VERSO di questo, accendendo il led.
I led sono dispositivi a bassa potenza e possono essere alimentati direttamente dalle linee di I/O del microcontrollore. Altri dispositivi invece richiedono molta piu' potenza e si rendono necessari appositi stadi driver. Il prossimo schema mostra come azionare una lampada a 220 Volt tramite la linea RB0 del microcontrollore:


Attivazione di una lampada a 220 Volt tramite la linea RB0

Quando sul bit RB0 viene posto uno 0, il transistor BC547 rimane interdetto, non scorre alcuna corrente lungo il ramo del rele che quindi non scatta e la lampada rimane spenta.
Quando sul bit RB0 viene posto un 1, il piedino RB0 si porta a VCC Volt ed inizia a scorrere una corrente verso massa, attraverso la base e l'emettitore del BC547; tale corrente e' di piccola entita' (limitata dalla resistenza da 10K) ma sufficiente a portare in conduzione il transistor, che quindi "diventa" un cortocircuito. Inizia a fluire corrente lungo il ramo del rele' che quindi si attiva e chiude il circuito al quale e' collegata la lampada.



Utilizzare i piedini come input


Per le linee B con resistenze interne di pull-up attivate e' sufficiente tenere scollegata la linea per avere un 1 logico, portarla a massa per ottenere uno 0 logico.
Nello schema seguente si setta un bit sulla linea RB0 tramite un semplice interruttore:


Schema per impostare lo stato della linea RB0 (resistenze interne di pull-up attivate!)

Se le resistenze interne di pull-up sono disattivate e' necessario presentare una tensione di +5 volt per avere un 1 logico o portare a massa per ottenere unno 0 logico, come nello schema seguente:


Schema per impostare lo stato della linea RB0 (resistenze interne di pull-up disattivate!)

Lo schema precedente e' obbligatorio per gli input delle linee A, per le quali non sono previste resistenze di pull-up interne attivabili via software come accade per le B.