I2C e bus USB

Attenzione! Questa pagina contiene materiale obsoleto Attenzione!

In questo tutorial non verrà spiegato cosa è e come si usano i bus I2C e USB. Semplicemente verrà illustrato un hardware e un programma minimale che permettono di usare un dispositivo I2C collegato al PC attraverso l'interfaccia USB. Come esempio è stato usato il DAC (Convertitore Digitale Analogico) MAX520  e una EEPROM (memoria non volatile, cancellabile) 24LC16.

Simili esempi sono presenti nelle pagine Rapsberry Pi: I2C con Bash, Rapsberry Pi: I2C in C e PIC18 come master I2C

E' stata utilizzata una scheda basata su FT2232H. Sul sito FTDI si trovano diversi esempi di codice ma sono tutt'altro che minimali (interfaccia grafica, multithreading...) e per cominciare non è certo  la strada più semplice.

Hardware

L'hardware è realizzabile su breadboard senza alcun problema ed è costituito da due integrati MAX520 e 24LC16; per verificare la funzionalità ne basta uno solo. Con modifiche prossime a zero potrebbero anche essere sostituiti da altri purché dotati di interfaccia I2C. Il motivo della scelta: due integrati che avevo nel cassetto...

L'hardware per verificare la funzionalità del convertitore USB I2C

Da notare le indicazioni della numerazione dei pin sul connettore a 40 poli: i più attenti noteranno che è inserito al contrario... Si tratta di una "features" della scheda che ho utilizzato.

Il LED sulla sinistra serve semplicemente per verificare la presenza dell'alimentazione, proveniente dal PC attraverso il bus USB. Non è indispensabile ma serve per evitare distrazioni dagli effetti potenzialmente catastrofici, anche per il vostro PC. La resistenza in serie non si vede ma evidentemente è presente.

Qui sotto trovate il semplice schema elettrico. Per la prima volta in questo sito è stato usato uno schema elettrico disegnato a mano (chi pensa ad un omaggio a Bop Pease... non si sbaglia). Se proprio non vi va, trovate pure la versione CAD.

Lo schema di collegamento di un bus i2c

I due segnali SDA e SCL sono generati direttamente dal'integrato FT2232H.

DAC MAX520

Il MAX520 contiene quattro convertitori digitale-analogico a otto bit ed ha interfaccia I2C. Ciascuno di essi converte un numero binario compreso tra 00000000 e 11111111 in una tensione continua compresa tra 0V e 5V

Memoria EEPROM 24LC16

Si tratta di una piccola memoria non volatile da 2k x 8bit con interfaccia seriale IIC. Il software dovrebbe funzionare senza modifiche anche con le versioni più vecchie e di minore capacità, siglate 24Cxx o qualcosa di simile.

Il codice

Prima di scrivere il programma occorre scaricare dal sito FTDI la libreria dinamica FTCI2C.DLL e relativi file di supporto. Non serve installazione ma vi conviene copiare la DLL direttamente nella cartella c:\windows\system32  (o simile). Si suppone inoltre che i driver FT2232H siano già installati e funzionanti.

Il codice è stato compilato con VisualC 2008. Il programma non fa altro che scrivere un byte su uno dei due dispositivi. Vi consiglio di leggere quanto segue avendo davanti la nota applicativa 109  Programming Guide for High Speed FTCI2C DLL disponibile sul sito FTDI e i manuali del componente che si vuole utilizzare.

Il codice mostrato è solo parziale, qui trovate la versione pronta per il copia e incolla.

DAC

Il seguente codice di esempio scrive un byte nel registro del DAC0. Per verificare l'effettivo funzionamento del programma occorre misurare la tensione in uscita con un multimetro: scrivendo per esempio il numero esadecimale 0x80 (128 in decimale, in pratica metà della tensione massima, corrispondente al codice 255) la tensione di uscita dovrà essere circa 2,5V.

ErrorCode = I2C_GetNumHiSpeedDevices(&DevicesFound);

Questa funzione individua quanti dispositivi FT2232H sono collegato al sistema. In realtà, trattandosi di dispositivi multipli il valore ritornato è pari a 2 per ciascun integrato.

if (ErrorCode != FTC_SUCCESS)
{printf ("Error! %d", ErrorCode ); return -1;}
else printf ("Found %d devices\n", DevicesFound );

Ogni volta che si invoca una funzione di ingresso/uscita è buona norma verificare la presenza di errori. In questo caso un errore semplicemente interrompe l'esecuzione del programma

I2C_GetHiSpeedDeviceNameLocIDChannel(0, DeviceNameBuffer, 100, &LocationID, Channel, 5, &HiSpeedDeviceType);
I2C_OpenHiSpeedDevice(DeviceNameBuffer, LocationID, Channel, &IicDeviceHandle);
I2C_TurnOnDivideByFiveClockingHiSpeedDevice(IicDeviceHandle);
I2C_InitDevice(IicDeviceHandle, CLOCK_DIVISOR);

L'insieme di queste quattro funzioni inizializza la comunicazione tra PC e circuito integrato, definendo le opportune variabili e impostando gli opportuni registri. L'unica cosa che forse va sottolineata è che tutto le operazioni avranno come destinazione la "maniglia" IicDeviceHandle che è null'altro che un puntatore ad una struttura che contiene i dettagli del dispositivo.

WriteControlBuffer[0] = DAC_ADDR; // See MAX520 data sheet: Address Byte
WriteControlBuffer[1] = DAC_CTRL; // See MAX520 data sheet: Command Byte

Questo vettore contiene i codici specifici di controllo da inviare al DAC, in pratica l'indirizzo del MAX520 e quale dei quattro DAC verrà utilizzato. I dettagli vanno cercati sui fogli tecnici del MAX520

Ovviamente se usate altri circuiti integrati i codici saranno diversi anche se simili.

WriteDataBuffer[0] = DAC_DATA; // Data to write - 8 bit 0-255

Questo byte imposta la tensione in uscita: l'intervallo numerico 0-255 determina una tensione tra 0 V e 5 V

I2C_Write(IicDeviceHandle, &WriteControlBuffer, 2, true, 20, true, BYTE_WRITE_TYPE, &WriteDataBuffer, 1, true, 20, &PageWriteData);

Questa funzione è quella che effettivamente scrive i bit sul bus IIC

Alla fine del programma occorre invocare I2C_Close(IicDeviceHandle), dall'ovvio significato

Il codice per collegare lo stesso DAC ad un PIC18 lo trovate su PIC18 come master I2C

EEPROM

Questo programma scrive un byte sulla memoria e quindi lo rilegge. Il codice è sostanzialmente uguale al precedente. L'unica differenza è l'uso della funzione I2C_Read() il cui significato è ovvio.

Verifica del funzionamento

Le immagini seguenti mostrano i due segnali SDA (in giallo) e SCL (in azzurro) nei seguenti due casi:

I segnali SDA e SCL durante la trasmissione di un dato da master a slave I segnali SDA e SCL durante la trasmissione di un indirizzo

Tali segnali sono facilmente sovrapponibili a quelli teorici e confermano il corretto funzionamento del dispositivo.

Un problema piuttosto grave, del quale non ho trovato documentazione sul sito FTDI, è l'estrema lentezza della trasmissione. Non si tratta ovviamente di un problema di clock (dalle due schermate precedenti si osserva che la frequenza è quella nominale di circa 400 kHz) ma di "latenza" cioè di tempo necessario tra la trasmissione di un byte e l'altro.

L'immagine che segue illustra il problema, mostrando la trasmissione di tre byte:

Latenza nella trasmissione I2C con FT2232H

La traccia gialla è il clock, molto compresso in senso orizzontale. Si noti che la base dei tempi è oltre mille volte minore che nelle due schermate precedenti e che quindi quello che appare come un semplice tratto verticale è in realtà formato dalle otto transizioni necessarie per trasmettere un byte.

La traccia azzurra non è SDA ma un segnale opportunamente generato da un microcontrollore PIC che permette di identificare facilmente la trasmissione di un dato (presenza del tratto azzurro, primo e terzo evento) o di un indirizzo (evento centrale).

Il tempo richiesto tra un byte ed il successivo è dell'ordine di 10-20 ms (tempo peraltro molto variabile). Questo significa che la velocità media effettiva è dell'ordine di qualche centinaio di byte al secondo.

La spiegazione dipende dalla latenza tipica dello stack USB, dell'ordine di 15 ms, che diventa disastrosa nel caso sia necessario trasmettere un singolo byte. Infatti per trasmettere un dato o un indirizzo è necessario:

  1. Inviare in un frame USB il byte, dal PC a FT2232H (tempo richiesto: 15 ms circa)
  2. Attendere che lo slave risponda con l'ACK (microsecondi se la periferica è normalmente veloce)
  3. Trasmettere l'ACK da FT2232H al PC attraverso l'USB (tempo richiesto: 15 ms circa)

Tra le strade percorribili:

Scarica il codice sorgente e lo schema completo

Licenza "Creative Commons" - Attribuzione-Condividi allo stesso modo 3.0 Unported


Pagina principaleAccessibilitàNote legaliPosta elettronicaXHTML 1.0 StrictCSS 3

Vai in cima