1pin = ingresso e uscita ?
|
...mancano sempre pin...
Si sa che i microcontroller hanno un numero di pin di I/O
variabile tra poche unità e un centinaio; però, dato che i componenti più economici e "maneggevoli" sono quelli con
un numero limitato di pin, da 6 a 28, ci si può trovare, a volte, ad avere bisogno
qualche I/O in più rispetto a quelli disponibili.
Le soluzioni possibili sono diverse: cambiare chip, usandone uno con
un maggior numero di pin oppure aggiungere I/O expander su I2C o SPI.
In ogni caso abbiamo un costo e un impegno di
superficie dello stampato superiore e complicazione del circuito che possono essere
sensibili.
Abbiamo visto, però, come sia possibile comandare più carichi
con un solo pin, espandendo così il numero di uscite disponibili; non c'è
una soluzione anche nel caso in cui servano più ingressi o una combinazione
di ingressi/uscite maggiore del numero dei pin ?
In effetti esistono possibili soluzioni che permettono di
utilizzare un pin sia come input che come output, ricevendo dall'esterno un
livello logico e comandando un carico.
Vediamo cosa è possibile fare, vantaggi e svantaggi.
1 PIN digitale = 1 input +
1 output
Può capitare la necessità di ricevere segnali dall' esterno
(contatti, livelli logici) e di dovere comandare carichi con corrente massima
fino alla portata del pin (tipicamente 25mA).
Se intendiamo utilizzare un solo pin per entrambe le funzioni,
dobbiamo per prima cosa tenere presente che ci sarà una fondamentale
limitazione: non è possibile utilizzare contemporaneamente un pin come
ingresso e come uscita. Le due azioni sono esercitabili solo in momenti
diversi.
E' un limite grave? In effetti potrebbe esserlo molto meno di
quanto si possa pensare: in molte applicazioni occorre azionare una uscita in
conseguenza di un ingresso, ovvero rilevare lo stato dell'ingresso e
poi azionare l'uscita. Questo è un caso in cui un solo pin può effettuare
entrambe le funzioni: per un certo periodo sarà un ingresso; una volta
arrivato il segnale richiesto, diventerà una uscita per comandare il carico
voluto.
Basta realizzare un hardware adeguato, possibile con l'aggiunta di ben poche parti.
Consideriamo lo schema seguente: si tratta di una
configurazione comune per un contatto o pulsante. Il pin è configurato come ingresso; è mantenuto a livello
alto dal pull-up R1, che potrà essere un resistore esterno o un weak
pull-up integrato, se disponibile.
L'elemento di input schematizzato è il pulsante S1:
- se è aperto, il livello
logico del pin è stabilito dal pull-up.
- se chiudiamo a massa il
contatto, il livello logico andrà a 0 attraverso la R2, che è di
valore molto minore di R1.
|
|
Consideriamo ora una uscita che comanda un LED, un opto
isolatore, un relay a stato solido o un altro carico all'interno delle
possibilità del pin::
Se il pin, configurato come uscita, è a livello alto, una
corrente limitata da R3 fa accendere il LED. La presenza del pull-up
R1 non influisce sul circuito in quanto il suo valore molto elevato
impedisce lo scorrere di una corrente che possa accendere il led.
|
|
Ma effettuiamo ora un merge tra i due schemi:
Se il pin è configurato come uscita, portandolo a livello
alto azioniamo il carico, con una corrente limitata da R3.
La presenza di S1 è indifferente: se è aperto è come se non ci fosse,
se è chiuso fa assorbire una corrente limitata da R2. Basta che la
somma delle due correnti sia nel limite delle possibilità del pin.
Se il pin è configurato come ingresso, il carico sarà disabilitato,
in quanto la corrente attraverso R1 non sarà sufficiente ad accendere
il LED.
Per contro, il livello logico sarà determinato dalla situazione di S1.
|
|
Si potrà obiettare che, con il pin configurato come ingresso e con S1 aperto, il
livello di tensione è stabilito dal partitore formato da R1/R3-LED.
Questa tensione potrebbe trovarsi in una zona di indecisione per il port TTL.
Il trucco che permette alla cosa di funzionare consiste nel
diodo D1 in serie al LED: tipicamente la caduta di tensione di conduzione del LED
è attorno a 2V e quella del diodo attorno a 0.6V. Questo vuol dire che
al pin ci sarà, per S1 aperto, una tensione maggiore dei 2.4V necessari
perchè il port identifichi un livello alto.
Se si utilizzano LED rossi con tensione di conduzione di 1.7-1.8V sarà
opportuno sostituire il D1 con uno zener da 2.7V.
Se si utilizzano LED colorati con tensione
tipica di 3.4V, il diodo in serie non dovrebbe servire.
La corrente che attraversa i diodi è limitata dalla
serie R1+R3, dove R1 è di valore molto elevato, tale da far circolare una
corrente così piccola da non poter accendere il LED fino a che non si porta
il pin come uscita a livello alto.
|
|
Avvertenza: la tensione di conduzione dei diodi dipende
in modo diretto dalla corrente; più è bassa la corrente che lo attraversa,
più sarà bassa la tensione ai suoi capi.
Così, ad esempio, un 1N4148, che dichiara sul foglio dati una Vf tra
0.6 e 07V a 5mA, che diventa 1V a 100mA, nelle condizioni dello schema qui
sopra sarà dell' ordine di 0.4-0.5V. Di questo va tenuto conto nel calcolo
per raggiungere il livello di tensione voluta.
In conclusione, avremo il seguente funzionamento:
Pin impostato come ingresso
Il livello del pin sarà determinato dalla situazione di S1.
Il LED sarà sempre spento.
Direzione
pin |
S1 |
livello
al pin |
LED |
input |
aperto |
alto |
off |
chiuso |
basso |
off |
In effetti nel LED passerà comunque una corrente, determinata
essenzialmente da R1, ma, dato che il suo valore sarà maggiore di 47k, la
corrente risultante sarà tale da non provocare alcun effetto visibile.
Pin impostato come uscita
Se il livello imposto al pin, configurato come uscita, è
basso, il LED sarà spento.
Se imponiamo un livello alto, il LED si accenderà, con una corrente limitata
da R3 e dalla cdt sul diodo.
Direzione
pin |
S1 |
livello
imposto |
LED |
Corrente |
out |
aperto |
basso |
off |
- |
aperto |
alto |
on |
R3 |
chiuso |
basso |
off |
- |
chiuso |
alto |
on |
R2 e R3 |
Lo stato di S1 è indifferente; si avrà solo un aumento della
corrente erogata dal pin a livello alto quando S1 è chiuso.
Quindi, utilizzeremo la seguente regola:
-
Il pin configurato come ingresso riceve il livello
logico presente, che dipende solo da S1.
-
Il LED sarà spento con il pin configurato come
ingresso e acceso con il pin configurato come uscita e posto a livello
alto.
Se occorre comandare un carico elevato basterà
utilizzare un optomos o un SSR (Solid State Relay) al posto o in serie al LED.
Ne esistono moltissimi modelli in grado di sostenere
direttamente carichi da poche
centinaia di mA a molti ampere, sia in cc o ca, garantendo inoltre un
isolamento galvanico col carico.
Ad esempio, nello schema, un triac driver zero crossing della serie
MOC (per 230V va usato MOC3060-3063).
|
|
Dato che è possibile cambiare dinamicamente da programma la
direzione dell'I/O, si potrà avere con semplicità un funzionamento "half
duplex":
-
il pin è
configurato come ingresso: il micro attende un segnale sull'ingresso.
-
Una volta recepito il segnale, si potrà commutare il pin
come uscita a livello alto per comandare il carico
A questo punto, ci può essere la possibilità di continuare a disporre
anche della funzione di ingresso. Si potrà portare il pin come input e
testarne il livello per breve tempo, dell'ordine delle frazioni di secondo,
per poi riportarlo come uscita a comandare il carico.
Questo è possibile solo se il carico può ammettere delle brevi
mancanze di alimentazione; ad esempio, se sospendiamo l'uscita per qualche
millisecondo ogni secondo per verificare lo stato di S1, non otterremo alcuna
differenza nella luminosità del LED. Se ripetiamo con una frequenza maggiore
l'operazione in sostanza alimenteremo il LED con un duty cycle diverso dal
100% e questo potrà influire sulla luminosità.
Se il carico è costituito da qualcosa di
diverso da un LED, come un opto isolatore, un relè a stato
solido e simili, occorrerà
verificare caso per caso se la commutazione in/out è possibile e entro che
limiti.
Con un clock di 4MHz è possibile invertire la direzione del
pin, verificarne lo stato e riportarlo come uscita in una decina di
microsecondi, il che costituisce un tempo di mancata alimentazione che molti
tipi di carico possono sopportare.
Però, nel minimizzare i tempi di commutazione,
occorre tenere presente che i cablaggi e i componenti possono introdurre capacità
parassite che rendono necessario un tempo minimo di attesa tra la commutazione
e la lettura dello stato dell'ingresso, al
di sotto del quale si potranno avere rilevamenti del livello logico ingresso non
corretti.
Dal punto di vista pratico:
R1 |
un weak pull-up interno o un pull-up esterno di valore compreso tra
22k-47k. Non è critico. Minore il valore, maggiore la corrente.
Maggiore il valore, minore la corrente, ma anche l'effetto del
pull-up. |
R2 |
tipicamente 1k. Non è critica. Il suo scopo è quello di
limitare la corrente in S1 nel caso di pin come uscita. Ha anche un
effetto nel limitare eventuali disturbi ESD presenti sul pulsante. |
R3 |
dipende dal carico. Può essere dimensionata per far passare da 2 a
20mA. |
D1 |
serve ad aggiungere una cdt a quella del LED in modo da avere > 2.4V complessivi.
Se si usano LED rossi, si può utilizzare uno zener da 2.7V |
LED |
se si impiegano LED bianchi o blu, la loro cdt è già a livello
tale (3.4V - 4.3V) da non richiedere la presenza di D1. |
Un appunto per quanto riguarda i pin.
Non tutti i pin sono uguali. In generale abbiamo due possibili situazioni come ingressi:
Se nel caso di compatibilità TTL il livello logico alto è
2.4V, nel caso di ST (Schmitt Trigger) il livello riconosciuto come alto è
0.8Vdd: per una Vdd di 5V, si tratta di 4.3V.
Se vogliamo usare il sistema descritto su pin TTL occorrerà
che la cdt complessiva del carico sia almeno 2.4V. Se l'ingresso è ST
occorrerà 0.8Vdd, che si ottiene o con
LED ad alta tensione di conduzione oppure inserendo più LED o diodi in
serie.
1 PIN analogico = 1 output
+ n preselezioni.
Un altro caso che può capitare è quello di avere alcune
impostazioni selezionabili da jumper che vanno configurati prima di avviare il
dispositivo.
Anche in questo caso possiamo utilizzare un sistema simile al precedente:
occorre, questa volta, un pin configurabile come ingresso analogico, ovvero un
chip dotato di modulo ADC.
All'accensione, il pin viene configurato come ingresso
analogico.
Un jumper a due posizioni permette di introdurre due tensioni
diverse, che la lettura attraverso il modulo ADC permetterà di
discriminare, ottenendo due possibili selezioni.
Il transistor non andrà in conduzione in quanto abbiamo cura di
realizzare un partitore che non invii una tensione maggiore di quella
dello zener. Così, per qualsiasi posizione del jumper, il
transistor sarà interdetto.
Una volta catturato l'ingresso, commutando come uscita digitale il
pin,sarà possibile azionare il transistor mandando il pin stesso
a livello alto.
|
|
Il trucco consiste nel limitare le tensioni selezionabili dal
partitore ad un livello inferiore a quella dello zener; in questo modo il
transistor andrà in conduzione solamente quando il pin, configurato come
uscita, sarà posto a livello alto.
Ad esempio, per una Vdd di 5V, potremo scegliere R2=R3=10k e
R1=30k, il che rende 2V al pin 1 del jumper e 1V al pin 2. Lo zener sarà da
2.7-3V.
Ovviamente possiamo avere più selezioni per il jumper,
realizzando un partitore a più livelli, ad esempio 4, distanti 0.5V uno dall'
altro.
R2=R3=R5=R6=10k
R1=60k
V1=0.5V
V3=1V
V5=1.5V
V7=2V
|
|
Avvertenza: in tutti i casi, un jumper deve essere comunque
inserito,
altrimenti il livello logico al pin sarà imprevedibile.
Quando il pin è configurato come uscita a livello alto,
l'unico effetto dei jumper sarà quello di derivare una corrente verso massa
in proporzione al valore selezionato.
In tal senso, è opportuno che la R1 sia non inferiore a 1k, che equivale a
5mA con Vdd di 5V. In generale, più i valori del partitore sono alti, minore
sarà la corrente che attraversa le resistenze e quindi il consumo, cosa
importante per applicazioni a batteria.
La precisione del partitore non è importante, ma se si
aggiunge il fatto di utilizzare la Vdd come tensione di riferimento della
conversione AD, occorre una ragionevole stabilità dell' alimentazione ed
eventualmente una taratura dei risultati della conversione rispetto alle
tensioni selezionate dal partitore. La cosa comunque non è critica se si
mantiene un passo tra le tensioni selezionate abbastanza ampio, in modo da
utilizzare attivamente solo i bit più alti del risultato e potendo scartare i
meno significativi, il che riduce anche i possibili errori dovuti a rumore
indotto.
Queste applicazioni sono pensate per una Vdd tipica di 5V.
Se l'alimentazione è minore, può risultare difficile far funzionare i LED
desiderati e occorrerà verificare i livelli di tensione
necessari al corretto funzionamento del circuito. |
|