IL BUS I2C

Nonostante abbia oltre vent’anni, il bus I2C è ancora molto utilizzato nell’interfaccia con i microcontrollori. Ecco come funziona.

In molti progetti d’elettronica, anche afferenti ad ambiti tra loro diversi (industriale, telecomunicazioni, etc.), spesso è rintracciabile una situazione ricorrente in cui un dispositivo intelligente, il più delle volte un microcontrollore, si trova a doversi interfacciare con svariate periferiche quali memorie, convertitori A/D, Real Time Clock, etc. Proprio per la frequenza di questa situazione progettuale una ventina di anni fa la Philips sviluppò l’I2C, un bus di comunicazione di tipo seriale che semplificasse, in modo flessibile ed economico, l’interfacciamento tra varie tipologie di integrati (I2C o IIC sono l’acronimo di Inter-Integrated Circuit.).

Infatti, con questo bus non è necessario progettare nessuna interfaccia poiché i dispositivi I2C compatibili, di qualunque natura essi siano, hanno sul loro stesso chip tutta la circuiteria necessaria per essere direttamente inseriti sulla linea di comunicazione, inoltre, per la trasmissione e la ricezione sono necessarie due sole linee. Il numero di dispositivi collegabili è molto elevato e virtualmente dipende solo dalla capacità complessiva del bus. Prima di addentrarci nella descrizione dettagliata del bus identifichiamo le tipologie di interlocutori che vi possono essere collegati. Il bus I2C è bidirezionale, pertanto vi saranno presenti dispositivi in grado di trasmettere, di ricevere o di fare entrambe le cose (certo non contemporaneamente) a seconda delle loro esigenze di funzionamento.

E’ definito trasmettitore un dispositivo che invia dati sul bus. Di rimando è definito ricevitore un dispositivo che riceve dati dal bus. Oltre che in base alla direzione in cui transitano i dati, i dispositivi possono essere classificati in base alla loro capacità di richiedere o meno una comunicazione con un altro dispositivo. In particolare, si definisce master un dispositivo in grado di richiedere una comunicazione, generare il necessario segnale di clock e chiudere la comunicazione. Si definisce, invece, slave il dispositivo indirizzato da un master. Ad esempio il sensore di temperatura LM75 è uno slave in quanto non può richiedere nessuna comunicazione, ma deve essere interpellato da un altro dispositivo che provveda a fornirgli il segnale di clock. Invece può comportarsi da trasmettitore, inviando al master il valore della temperatura misurata, o da ricevitore, leggendo le impostazioni provenienti dal master.

Un microcontrollore può fungere da master o, se interrogato da un altro microcontrollore, da slave. Detto questo, possiamo definire l’I2C come un bus bidirezionale di tipo seriale, multi-master (in cui cioè più dispositivi possono assumere il controllo del bus) con velocità di comunicazione che raggiungono i 100 kbit/s nella modalità normale o i 400 kbit/s nella cosiddetta modalità veloce. La trasmissione dei dati avviene, come accennato, per mezzo di due sole linee denominate rispettivamente SDA (Serial Data) e SCL (Serial Clock). Sulla prima viaggiano effettivamente i bit di informazione che trasmettitore e ricevitore si scambiano. Sulla seconda linea viaggia il segnale di clock, generato sempre ed esclusivamente da un master (sia esso il trasmettitore o il ricevitore), il cui scopo è quello di sincronizzare i dispositivi stabilendo la validità e il significato dei bit presenti sulla linea dati. Se sul bus sono presenti più master ciascuno dovrà generare il proprio segnale di clock. Naturalmente, per evitare situazioni di conflitto in cui più master tentano di assumere contemporaneamente il controllo del bus, è stato previsto un meccanismo di arbitraggio: le uscite SCL e SDA dei dispositivi I2C sono di tipo open-drain o open-collector (Figura 2).

Figura 1: Esempio di bus I2C.

Figura 1: Esempio di bus I2C

 

Figura 2: Connessione dei dispositivi I2C sul bus.

Figura 2: Connessione dei dispositivi I2C sul bus

Questo, se da una parte richiede che le due linee siano collegate all'alimentazione positiva tramite due resistenze di pull-up, dall’altra fa sì che tutti i dispositivi collegati al bus formino un and cablato, ossia diano luogo ad una situazione in cui le due linee rimangono alte se e solo se tutte le uscite sono alte, viceversa è sufficiente che una sola uscita vada bassa perché la linea corrispondente si porti nello stato logico basso. In questa maniera se un master sta trasmettendo un livello alto mentre un altro invia un livello basso, esso riuscirà a rilevare il conflitto in quanto il livello sulla linea non corrisponde a quello da lui inviato disattivando la propria uscita, mentre il bus risulta automaticamente assegnato al dispositivo che trasmette un livello basso.

Con le due resistenze di pull-up si esaurisce l’hardware da montare per utilizzare il bus I2C. Naturalmente la loro scelta non è casuale, ma dipende da considerazioni sulla velocità di trasmissione (legata alla capacità complessiva della linea) e sui margini di rumore come vedremo più avanti. Analizziamo, ora, il protocollo di comunicazione, ossia l’insieme di regole che i dispositivi devono seguire per comunicare con successo. Abbiamo detto che sulla linea SDA viaggiano i dati, mentre sulla linea SCL viaggia il clock generato dal master di turno. I dati sulla linea SDA sono considerati validi in corrispondenza dei livelli alti del clock. Ciò vuol dire che il dispositivo che sta trasmettendo può cambiare i bit sulla linea dati esclusivamente in corrispondenza dei livelli bassi del clock (Figura 3).

Figura 3: Trasferimento dei bit.

Figura 3: Trasferimento dei bit

A questa regola esistono solo due eccezioni utilizzate per indicare due situazioni particolari: l’inizio di una comunicazione da parte di un master e la corrispondente chiusura. Quando un master intende intraprendere una comunicazione deve generare una transizione da alto a basso sulla linea dati in corrispondenza di un livello alto del clock. Tale condizione è chiamata condizione di START. Quando il master intende chiudere la comunicazione, deve generare una transizione da basso ad alto su SDA, in corrispondenza di un livello alto su SCL. Tale condizione viene detta di STOP. L’informazione che deve essere scambiata nel corso della comunicazione è racchiusa tra una condizione di start e una condizione di stop (Figura 4).

Figura 4: Asserito delle condizioni di START e STOP.

Figura 4: Asserito delle condizioni di START e STOP

Nulla vieta, comunque, che un master, terminata la comunicazione con un certo slave, ne intraprenda una nuova con un altro generando un'ulteriore condizione di start e producendo un'unica condizione finale di stop. L’unità di informazione che può essere trasmessa è il byte (8- bit). Non esiste un limite teorico al numero di byte che può essere trasmesso nel corso di un singolo trasferimento. Nell’inviare un byte viene posto per primo il bit più significativo. In seguito all’invio di un byte il trasmettitore rilascia temporaneamente la linea dati (ovvero la pone nello stato alto) per consentire al ricevitore di porvi un bit di acknowledge che testimoni l’avvenuta ricezione. Pertanto una comunicazione elementare richiede nove colpi di clock: otto per il byte e uno per l’acknowledge (Figura 5).

Figura 5: Invio del primo byte e bit di acknowledge.

Figura 5: Invio del primo byte e bit di acknowledge

Il primo byte inviato successivamente alla condizione di start, contiene l’indirizzo dello slave con il quale si desidera stabilire la comunicazione e l'indicazione sul verso in cui avverrà la comunicazione stessa. In particolare, i primi sette bit codificano l’indirizzo dello slave e l’ottavo (R/W), se alto, indica una richiesta di dati, se basso indica una trasmissione (Figura 6).

Figura 6: Struttura del primo byte.

Figura 6: Struttura del primo byte

Quando viene ricevuto un indirizzo, ciascuno slave lo confronta con il proprio. Se viene trovata una corrispondenza, lo slave interessato risponde con un acknowledge e si pone a disposizione del master a seconda dello stato del bit R/W. A questo punto occorre spendere qualche parola sul modo in cui vengono assegnati gli indirizzi ai vari dispositivi. L’I2C, nella sua versione classica, destina, come detto, 7 bit all’identificazione di ciascun slave. Questo comporta che siano indirizzabili 128 dispositivi diversi (in realtà 112 perché alcuni indirizzi sono riservati). Sfruttare appieno questo spazio d’indirizzamento comporta che sul package di ciascun integrato I2C compatibile, vi siano 7 pin destinati esclusivamente alla sua identificazione.

Spesso questo è inaccettabile per ragioni di spazio e, al fine di ridurre le dimensioni del contenitore, si adotta la seguente soluzione: sul chip i sette bit di indirizzo vengono suddivisi in due parti di cui una viene fissata definitivamente dal costruttore e non è resa accessibile, l’altra rimane invece programmabile da parte dell’utente. Ad esempio, nel caso di un LM75 sono accessibili solo i tre bit meno significativi A2, A1, A0, mentre i rimanenti quattro sono collegati all'alimentazione positiva o negativa all’interno del chip stesso, per cui l’indirizzo dello slave è del tipo riportato in Figura 7.

Figura 7: Esempio d’indirizzo di uno slave LM75.

Figura 7: Esempio di indirizzo di uno slave LM75

Risulta evidente, allora, come il numero di bit programmabili disponibili per un integrato di un certo tipo, stabilisca il numero massimo di dispositivi di quel tipo collegabili al bus. Nel nostro esempio saranno collegabili solo otto LM75. Prima di passare ad illustrare le caratteristiche elettriche dell’interfaccia è bene accennare al fatto che esiste una versione per così dire estesa dell’I2C in cui il formato di indirizzamento degli slave è esteso da 7 a 10 bit per venire incontro all'esigenza di disporre di un maggiore numero di indirizzi. Per conservare la compatibilità con il formato a 7 bit, la soluzione adottata prevede l’invio di un primo byte (quello immediatamente successivo alla condizione di start) contenente cinque bit fissi nella configurazione 1110, i primi due bit dell’indirizzo e il bit di R/W, ed un secondo byte contenente i restanti otto bit dell’indirizzo. Ciascun byte è seguito dall’invio di un bit di acknowledge da parte dello slave. Quando viene inviato un indirizzo a 10 bit, ciascuno slave confronta i primi due bit con i propri. Probabilmente più dispositivi troveranno una corrispondenza e risponderanno con un primo acknowledge A1. Successivamente, questi stessi confronteranno il secondo byte di indirizzo con il proprio, e solo uno risponderà con un secondo acknowledge A2 (Figura 8). Questo slave rimarrà indirizzato

Figura 8: Indirizzamento a 10bit.

Figura 8: Indirizzamento a 10bit

dal master fintantoché non troverà sul bus una condizione di stop o una nuova condizione di start con un differente indirizzo di slave. Un’ulteriore estensione apportata dalla Philips riguarda la cosiddetta modalità veloce (fast mode), nella quale la velocità di comunicazione, normalmente inferiore o uguale ai 100 kbit/s, viene portata a 400 kbit/s. Naturalmente protocolli e formati rimangono inalterati. Di diverso vi sono degli accorgimenti elettrici (trigger di Schmitt sugli ingressi, pull-up attivi, etc.) per adattare i segnali alla maggiore velocità. Veniamo finalmente alle caratteristiche elettriche del bus e dei dispositivi I2C. Un parametro importante è il valore di capacità complessivo che il bus viene ad avere: le specifiche Philips fissano il massimo valore a 400 pF sia per la linea SDA che per la SCL. Per ciascun dispositivo viene stabilito un valore di capacità di ingresso non superiore ai 10 pF. La frequenza massima per SCL è, come già detto, di 100 kHz in normal mode e 400 kHz in fast mode. Per i livelli logici sono previsti dei margini di rumore pari a 0.1 Vdd per il livello basso e 0.2 Vdd per il livello alto, dove Vdd è la tensione di alimentazione positiva. Un altro aspetto da considerare è la scelta del valore per le due resistenze di pull-up Rp. Esso dipende dalla tensione d’alimentazione, dalla capacità del bus e dal numero dei dispositivi connessi. Poiché si richiede che la massima tensione d’uscita che risulti ancora accettabile come uno zero logico dagli altri dispositivi sia VOL,MAX= 0.4 V con una corrente minima Imin= 3 mA (Figura 9), risulterà un limite inferiore per il valore di Rp:

Rpmin=(Vdd-0.4)/0.003

Figura 9: Valore minimo della tensione d’uscita dei driver I2C.

Figura 9: Valore minimo della tensione d’uscita dei driver I2C

Ad esempio, se Vdd=5 V, le resistenze di pull-up non devono avere valore inferiore a 1.5 kW. Il valore minimo delle resistenze dipende dalla tensione di alimentazione e varia con esso in modo lineare, come in Figura 10.

Figura 10: Andamento del valore minimo della resistenza di pull-up con la tensione d’alimentazione.

Figura 10: Andamento del valore minimo della resistenza di pull-up con la tensione d’alimentazione

D’altra parte, la capacità del bus (ossia la somma delle capacità di tutti i fili e di tutti i pin), e i margini di rumore previsti dalle specifiche per il livello alto (0.2 Vdd con corrente massima di 10 mA) limitano il massimo valore accettabile per Rp (Figura 11).

Figura 11: Andamento del valore massimo della resistenza di pull-up in funzione della capacità elettrica del bus.

Figura 11: Andamento del valore massimo della resistenza di pull-up in funzione della capacità elettrica del bus

Da un punto di vista pratico, senza fare troppi conti, possiamo considerare 4.7 kW un valore adeguato per una gran parte di applicazioni. Infatti, ipotizzando una tensione d’alimentazione di 5 V, con tale valore di resistenza è possibile pilotare fino a 200 pF, ossia più di 20 integrati.

Scarica subito una copia gratis

Una risposta

  1. Avatar photo Salvatore D'Ambrosio 10 Febbraio 2021

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend