Example code 05

Dependencies:   TextLCD mbed

Fork of STMNucleoF401RE_ExampleCode_05_LCD by Corso STM32Nucleo401RE

Come utilizzare il bus I2C

Il livello fisico del bus I2C

Si tratta di un bus costituito da due soli fili, detti SCL ed SDA, rispettivamente la linea di clock, utilizzata per il trasferimento di tutti i dati sul bus I2C, e la linea dati. Le due linee, SCL ed SDA, sono connesse a tutti i dispositivi sul bus I2C. Inoltre e' necessario che massa ed alimentazione a 5 V siano distribuite a tutti i dispositivi connessi al bus. Entrambe le linee SCL ed SDA sono del tipo "open drain". Cio' significa che il chip puo' mettere allo stato low l'uscita, ma non allo stato alto. Per far passare la linea allo stato alto e' necessaria un resistore di pull-up. Dovrebbe esserci un resistore di pull-up per ciascuna linea, ma sono necessari resistori per l'intero bus e non per ciascun dispositivo, come indicato nella figura di seguito.

/media/uploads/perlatecnica/i2cpullupresistors.png

I valori di resistenza non sono critici, ma se mancano, le linee SCL ed SDA saranno sempre nello stato basso, 0 volts, e I2C bus non funzionerà.

Masters and Slaves

Le periferiche su un bus I2C sono o masters o slaves. Il master e' sempre il device che controlla il segnale di clock SCL. Gli slaves sono tutti gli altri dispositivi che rispondono al master. Un dispositivo slave non può iniziare un trasferimento sul bus I2C, solo il master può farlo. Sul bus possono esserci piu slaves, ma tipicamente un solo master. Ci sono dei casi in cui sono ammessi piu' masters ma non affrontiamo questo argomento qui. Esempi di dispositivi slaves possono essere il sensore ad ultrasuoni SRF08 e la bussola CMPS03. I dispositivi slaves non inizieranno mai la comunicazione. Entrambe, master e slaves possono trasferire dati sul bus ma il trasferimento e' sempre controllato dal master.

Il protocollo del livello fisico del bus I2C

Quando il master vuole comunicare con un dispositivo slave, inizia inviando una start sequence sul bus I2C. La start sequence e' una di due sequenze speciali definite per il bud I2C, essendo la seconda la stop sequence. Queste sequence sono speciali poiché rappresentano l'unico caso dove e' possibile inviare dati sulla linea SDA mentre il segnale di clock SCL e' nello stato alto. Quando un dato deve essere inviato, SDA deve restare stabile e non cambiare mentre l'SCL e' alto. La sequenza di start e stop marcano l'inizio e la fine della transazione con il device slave.

/media/uploads/perlatecnica/startstopseq.png

I dati sono trasferiti in sequenze di 8 bits. I bits sono trasmessi sulla linea SDA inviando prima il Most Significant Bit. Per ciascuna sequenza di 8 bits trasmessi, il dispostivo ricevente trasmette un bit di acknowledge, dunque il numero di impulsi di clock per il trasferimento di un byte di dati e' nove.

/media/uploads/perlatecnica/databyte.png

Se il dispositivo ricevente invia un ACK bit basso, significa che il dato e' stato ricevuto ed e' pronto ad accettare un altro byte. Se il dispositivo ricevente invia un ACK bit alto, questo significa che non può accettare ulteriori dati ed il master dovrebbe terminare il trasferimento ed inviare una sequenza di stop. Il clock (SCL) secondo lo standard e' fino a 100KHz.

Indirizzamento dei dispositivi I2C

Tutti gli indirizzi dei dispositivi su bus I2C, sono o 7 oppure 10 bits. L'uso di 10 bits e' raro e non coperto qui. Tipicamente gli indirizzi sono a 7 bits. Questo significa che con questo indirizzamento e' possibile avere fino a 2^7 = 128 dispositivi. Anche se l'indirizzo e' espresso su 7 bits, bisogna comunque inviarne 8. L'extra bit viene utilizzato per informare lo slave se il master sta scrivendo a questo o sta leggendo. Se il bit e' zero, il master sta scrivendo allo slave. Se il bit e' 1, allora il master sta leggendo dallo slave. L'indirizzo del dispositivo e' nei primi 7 bits, quelli piu' significativi, mentre il bit di Read/Write e' LSB (Least Significant Bit).

/media/uploads/perlatecnica/addressbyte.png

La posizione dei 7 bit di indirizzo nei primi 7 bits, quelli più significativi, può essere sorgente di confusione. Se ad esempio si deve comunicare con un dispositivo che ha indirizzo 21, bisogna inviare un byte 42 che rappresenta 21 spostato a sinistra di un bit. Probabilmente e' più semplice pensare ad un indirizzamento ad 8 bit dove gli indirizzi pari sono per scrivere e quelli dispari per leggere. Ad esempio l'indirizzo 0xC0 viene utilizzato per scrivere e l'indirizzo 0xC1 per leggere.

Il Software Protocol

Scrivere su un dispositivo slave

La prima cosa che accade e' che il master inizia una start sequence. Questo avvisa tutti gli slaves collegati sul bus, che e' iniziata una transazione e che devono ascoltare se il messaggio e' indirizzato a loro. Poi il master invia il byte di indirizzo del dispositivo che deve ricevere i dati. Lo slave il cui indirizzo corrisponde a quello inviato dal master. Lo slave indirizzato, sara' l'unico a continuare nell'ascolto della trasmissione, gli altri aspetteranno il prossimo. Avendo indirizzato il dispositivo, il master può continuare nella trasmissione. Quindi invia la locazione o il registro dello slave che intende leggere o scrivere. Il numero dipende naturalmente dallo slave e da quanti registri dispone. A questo punto il master può inviare i data bytes. Il master può continuare ad inviare data bytes e questi verranno scritti nella locazione indirizzata poiché lo slave che sta ricevendo i dati automaticamente incrementa l'indirizzo del registro dopo ciascun byte. Quando il master ha finito di inviare tutti i data bytes allo slave, manderà una stop sequence per completare la trasmissione. Riassumendo per scrivere su un dispositivo slave e' necessario seguire la seguente procedura:

  • 1. Inviare una start sequence;
  • 2. Inviare l'indirizzo dello slave con il bit R/W (bit low - even);
  • 3. Inviare l'indirizzo interno del registro che si vuole scrivere;
  • 4. Inviare i data bytes;
  • 5. Inviare la stop sequence.

Leggere da un dispositivo slave

Leggere da un dispositivo e' leggermente più complicato. Prima di leggere dati da un dispositivo slave, bisogna specificare quale dei suoi registri interni si vuole leggere. Questo consiste in una scrittura. Cioè prima di leggere dal dispositivo bisogna eseguire una scrittura. Quindi in questo caso la bisogna eseguire una procedura più complessa e che possiamo riassumere come segue.

  • 1. Inviare una start sequence;
  • 2. Inviare l'indirizzo dello slave con il bit R/W (bit low - even address);
  • 3. Inviare Internal address of the bearing register;
  • 4. Inviare una start sequence (repeated start);
  • 5. Inviare l'indirizzo dello slave con il bit R/W (bit high - odd address);
  • 6. Leggere i data bytes;
  • 7. Inviare una stop sequence.

Questa comunicazione e' piuttosto semplice, ma può presentarsi una complicazione nel caso in cui lo slave che si sta leggendo, non e' una memoria ad esempio, ma un microcontrollore che sta svolgendo una funzione e potrebbe non essere pronto. In questo caso lo slave e' autorizzato a tenere basso il segnale SCL. Questo e' chiamato clock stretching. Dal punto di vista del master, questo attende che il segnale di clock venga rilasciato dallo slave. Fortunatamente questa operazione viene eseguita automaticamente dall'hardware in buona parte dei microprocessori.

Lo standard

Lo standard può essere scaricato al seguente link al momento http://www.nxp.com/documents/user_manual/UM10204.pdf

Download repository: zip gz

Files at revision 5:d261737139c5

Name Size Actions
[up]
TextLCD.lib 100 Revisions Annotate
main.cpp 1194 Revisions Annotate
mbed.bld 65 Revisions Annotate