Salta la barra di navigazione [1] - Vai alla barra di navigazione [3] - Scrivimi una mail [4]

Master I2C - PLIB

PIC18 in C - Sommario - Novità - Tutorial - Progetti - Risorse - Non solo elettronica

Il circuito è stato realizzato su breadboard

Attenzione! Le PLIB sono dal luglio 2015 sconsigliate per nuovi progetti Attenzione!

In questa pagina verranno mostrati alcuni esempi di codice per collegare una periferica I2C ad un PIC18 usando le PLIB. Verranno utilizzati due periferiche piuttosto diffuse: un sensore di temperature LM92 ed un'interfaccia digitale di ingresso/uscita MCP23017.

Non verrà qui spiegato cosa è e come si usa il bus I2C. Semplicemente verranno presentati un paio di esempi che permettono di comprendere come usare un dispositivo I2C collegato ad un PIC. Qui qualche informazione.

Il circuito è stato realizzato su breadboard e per lo sviluppo del software è stato utilizzato MPLAB X e XC8. Si è scelto di utilizzare le librerie PLIB.

L'hardware

Il PIC18 contiene al proprio interno un modulo hardware MSSP adatto, tra le altre cose, a funzionare come master I2C.

Il circuito utilizzato per le prove è costituito da un PIC18F14K50 e due dispositivi I2C, tra di loro assolutamente indipendenti e scelti solo perché "erano nel cassetto":

Ovviamente siete liberi di usare anche altri circuiti integrati: dovrete solo fare modiche al software, più o meno grandi a seconda della tipologia dell'integrato stesso. (esercizio 1)

I2C: LM92 e MCP23017 collegati al PIC18

Il circuito è costituito dai due integrati con le linee SDA e SCL collegate direttamente al PIC18. Le due resistenze di pull-up R2 e R3, collegate a SDA e SCL, sono obbligatorie ed il loro valore deve essere compreso tra 2 e 10 kΩ. Indicativamente è meglio evitare di scegliere i valori più alti per le frequenze di clock I2C più elevate, in quanto i tempi di salita del clock e del segnale sono direttamente proporzionale al valore di tale resistenza.

Anche i valori delle resistenze R4 → R11 non sono critici: possono avere un valore compreso tra 100 e 470 Ω. Ovviamente più la resistenza è piccola, più i diodi sono luminosi.

Infine il valore di R1 è praticamente irrilevante, in quanto in esso scorre una corrente molto piccola: indicativamente 10 → 100 KΩ

I dispositivi I2C devono avere indirizzi di 7 bit diversi, impostati in parte dal costruttore e in parte dall'utilizzatore.

Per MCP23017 è stato scelto l'indirizzo 0x20 impostando i tre bit meno significativi a zero, collegando i tre pi A2-A1-A0 a massa. La parte di indirizzo del dispositivo decisa dal costruttore e reperibile sui fogli tecnici è 0100. L'indirizzo complessivo è quindi 010 0000, 7 bit in totale. Ovviamente è possibile scegliere altri indirizzi, per esempio se è necessario collegare allo stesso bus più MCP23017.

Analogamente, la parte fissa dell'indirizzo di LM92 è 10010, la parte variabile scelta 11. L'indirizzo completo è quindi 100 1011, cioè 0x4B.

MCP23017

Il primo esempio che trovate a fondo pagina accende alcuni del LED collegati a PORTB (GPBx) dell'integrato MCP23017. Il PIC18 funziona come master mentre MCP23017 come slave.

Prima di iniziare ad usare il modulo occorre inizializzarlo ed impostare la frequenza del clock I2C, normalmente a 100 kHz, e quella del processore, in questo caso a 16 MHz. Da notare che queste due frequenze sono tra loro legate, come descritto nella tabella 15-3 del manuale del PIC18F14 e non tutte le combinazioni possibili sono conformi alle specifiche I2C.

OSCCON = 0x70; // Set internal clock to 16 MHz
SSPADD = 0x27; // Set 100 kHz clock ( @ 16 MHz )

Occorre quindi inizializzare la periferica MSSP:

OpenI2C(MASTER, SLEW_ON); // I2C Master mode, Slew rate enabled

Il primo parametro ha un significato ovvio. Il secondo attiva una opzione che permette di evitare fronti troppo ripidi durante le transizioni del clock e del dato (controllo dello slew rate). In genere quella indicata è l'opzione consigliabile se si lavora a 100 kHz. A 400 kHz questa opzione deve essere opportunamente valutata, a frequenze più elevate deve essere impostata preferibilmente a SLEW_OFF. Lo scopo è quello di ridurre le emissioni elettromagnetiche e le problematiche associate alla riflessione dei segnali lungo le linee.

Il cuore del codice è piuttosto semplice; nel caso in cui tutti i byte sono diretti dal PIC alla periferica la struttura è la seguente:

Il codice per le due sequenze di start e stop è gestito da due macro:

StartI2C(); // Send START condition
StopI2C();  // Send STOP condition

La scrittura di un byte, sia esso un indirizzo piuttosto che un dato, richiede:

IdleI2C();                // Wait until the bus is idle
if (WriteI2C(xx) < 0)     // Send Output
   I2C_error_handler(-1); // Errors?

Da notare che l'indirizzo (a 7 bit) deve essere traslato di una posizione verso sinistra e che il bit meno significativo deve rimanere a 0 nel caso di scrittura.

addrRW = MCP23017_ADDR << 1; // 7 bit address + Write bit (LSB = 0)

Il codice nel suo complesso trasmette a MCP23017 due pacchetti di tre byte ciascuno:

Una osservazione: questa funzione blocca il programma per tutto il tempo necessario alla trasmissione del byte. Potrebbe essere un progetto significativo (ma tutt'altro che breve e semplice) quanto descritto nell'approfondimento.

LM92

Il secondo esempio legge la temperatura misurata da LM92. A fondo pagina il codice completo.

La sequenza delle operazioni, è la seguente:

Gran parte del codice è uguale all'esempio precedente e quindi non verrà qui descritta nuovamente.

La prima differenza deriva dal fatto che i byte devono essere letti, cioè essere trasmessi dal LM92 al PIC18. Per fare ciò occorre forzare il bit meno significativo dell'indirizzo a 1:

addrRW = (LM92_ADDR << 1) | 0x01; // 7 bit address + Read bit (LSB = 1)

La lettura di un singolo byte, con trasmissione dell'ACK (o del NACK, se necessario):

IdleI2C();             // Wait until the bus is idle
buffer = ReadI2C();    // Read first byte of data
AckI2C();              // Send ACK

La parte finale del codice è specifica di LM92; per la comprensione occorre fare riferimento ai fogli tecnici di LM92, in particolare a Table 3 - TEMPERATURE REGISTER e relativa descrizione. Ovviamente non è possibile visualizzare la temperatura... Occorre bloccare il programma e leggere con il debugger di MPLABX il valore delle variabile temperature.

L'immagine seguente mostra i segnali presenti su SDA e SCL con relativa decodifica:

Segnali durante la lettura di LM92

Codice

Esercizi

  1. Scrivere il codice per utilizzare altri dispositivi I2C, in base alla effettiva disponibilità dei componenti

PIC18 in C

Appendici:

Qualche utile informazione integrativa: C per sistemi embedded

Licenza Creative Commons Attribuzione 4.0 Internazionale


EN - Pagina principale - Sommario - Accessibilità - Note legali e privacy policy - Posta elettronica

XHTML 1.0 Strict - CSS 3