Bus I2C/TWI

por | 25 julio, 2016

Al comenzar a usar Arduino puede resultar algo complejo entender las diferencias entre los diferentes tipos de interfaces de comunicación (y protocolos asociados).

Dentro la comunicación serie integrada en los microcontroladores de Arduino tenemos:

UART (recepción-transmisión asíncrona universal) es uno de los protocolos serie más utilizados. La mayoría de los microcontroladores disponen de hardware UART. Usa una línea de datos simple para transmitir y otra para recibir datos. Comúnmente, 8 bits de datos son transmitidos de la siguiente forma: un bit de inicio, a nivel bajo, 8 bits de datos y un bit de parada a nivel alto. UART se diferencia de SPI y I2C en que es asíncrono y los otros están sincronizados con señal de reloj. La velocidad de datos UART está limitado a 2Mbps

SPI es otro protocolo serie muy simple. Un maestro envía la señal de reloj, y tras cada pulso de reloj envía un bit al esclavo y recibe un bit de éste. Los nombres de las señales son por tanto SCK para el reloj, MOSI para el Maestro Out Esclavo In, y MISO para Maestro In Esclavo Out. Para controlar más de un esclavo es preciso utilizar SS (selección de esclavo).

I2C es un protocolo síncrono. I2C usa solo 2 cables, uno para el reloj (SCL) y otro para el dato (SDA). Esto significa que el maestro y el esclavo envían datos por el mismo cable, el cual es controlado por el maestro, que crea la señal de reloj. I2C no utiliza selección de esclavo, sino direccionamiento.

Dos o más señales a través del mismo cable pueden causar conflicto, y ocurrirían problemas si un dispositivo envía un 1 lógico al mismo tiempo que otro envía un 0. Por tanto el bus es “cableado” con dos resistencia para poner el bus a nivel alto, y los dispositivos envían niveles bajos. Si quieren enviar un nivel alto simplemente lo comunican al bus.

I2C es un bus de comunicaciones en serie. Su nombre viene de Inter-Integrated Circuit (Inter-Circuitos Integrados). La versión 1.0 data del año 1992 y la versión 2.1 del año 2000, su diseñador es Philips. La velocidad es de 100 kbit/s en el modo estándar, aunque también permite velocidades de 3.4 Mbit/s. Es un bus muy usado en la industria, principalmente para comunicar microcontroladores y sus periféricos en sistemas integrados (Embedded Systems) y generalizando más para comunicar circuitos integrados entre sí que normalmente residen en un mismo circuito impreso.

La principal característica de I2C es que utiliza dos líneas para transmitir la información: una para los datos y otra para la señal de reloj. También es necesaria una tercera línea, pero esta sólo es la referencia (masa). Como suelen comunicarse circuitos en una misma placa que comparten una misma masa esta tercera línea no suele ser necesaria.

Las líneas se llaman:

  • SDA: datos
  • SCL: reloj
  • GND: tierra

Los dispositivos conectados al bus I2C tienen una dirección única para cada uno. También pueden ser maestros o esclavos. El dispositivo maestro inicia la transferencia de datos y además genera la señal de reloj, pero no es necesario que el maestro sea siempre el mismo dispositivo, esta característica se la pueden ir pasando los dispositivos que tengan esa capacidad. Esta característica hace que al bus I2C se le denomine bus multimaestro.

Las líneas SDA y SCL son del tipo drenaje abierto, es decir, un estado similar al de colector abierto, pero asociadas a un transistor de efecto de campo (o FET). Se deben polarizar en estado alto (conectando a la alimentación por medio de resistores “pull-up”) lo que define una estructura de bus que permite conectar en paralelo múltiples entradas y salidas.

Más información en: http://es.wikipedia.org/wiki/I%C2%B2C

Comunicación I2C

El maestro comienza la comunicación enviando un patrón llamado “start condition”. Esto alerta a los dispositivos esclavos, poniéndolos a la espera de una transacción.

  • El maestro se dirige al dispositivo con el que quiere hablar, enviando un byte que contiene los siete bits (A7-A1) que componen la dirección del dispositivo esclavo con el que se quiere comunicar, y el octavo bit (A0) de menor peso se corresponde con la operación deseada (L/E), lectura=1 (recibir del esclavo) y escritura=0 (enviar al esclavo).
  • La dirección enviada es comparada por cada esclavo del bus con su propia dirección, si ambas coinciden, el esclavo se considera direccionado como esclavo-transmisor o esclavo-receptor dependiendo del bit R/W.
  • Cada byte leido/escrito por el maestro debe ser obligatoriamente reconocido por un bit de ACK por el dispositivo maestro/esclavo.
  • Cuando la comunicación finaliza, el maestro transmite una “stop condition” para dejar libre el bus.

Las transacciones en el bus I2C tienen este formato:

| start | A7 A6 A5 A4 A3 A2 A1 R/W | ACK | … DATA … | ACK | stop | idle |

I2C también se conoce como TWI (Two Wire Interface) y no dispone de un conector estandarizado.

Y mucha más información en: http://en.wikipedia.org/wiki/I%C2%B2C donde se explica la capa física más profundamente.

SMBus (Bus de Administración del Sistema) es un subconjunto del protocolo I2C definido por Intel en 1995. Todas las placas bases modernas tienen un bus SMBus al que se conectan la mayor parte de los chips de monitorización del sistema. Estos chips sirven para medir temperaturas de componentes, velocidad de ventiladores, voltajes, etc. Toda clase de información sobre hardware.

La principal diferencia de protocolos como el SPI o el I2C, y la comunicación serie que hemos visto anteriormente es que la USART (UART en este caso) no necesita un pin de señal de reloj entre ambos dispositivos para realizar la comunicación. Cada dispositivo se pone de acuerdo en la velocidad a la que se va a realizar la transmisión (se fija la velocidad), y después de una condición de inicio cada dispositivo muestrea los bits en el tiempo acordado, por lo que sólo son necesarios dos pines para que el micro pueda enviar y recibir datos.

Aplicaciones I2C: http://en.wikipedia.org/wiki/I%C2%B2C#Applications

Especificación y manual de usuario de I2C: http://www.nxp.com/documents/user_manual/UM10204.pdf

Listado de productos I2C: http://www.nxp.com/products/interface_and_connectivity/i2c/

I2C bus y como usarlo: http://www.i2c-bus.org/fileadmin/ftp/i2c_bus_specification_1995.pdf

I2C no tiene limitaciones de velocidad, el maestro genera la velocidad de reloj y I2C provee de un mecanismo que si el esclavo es más lento es capaz de ponerse el maestro en modo de espera.

En principio, el número de dispositivos que se puede conectar al bus no tiene límites, aunque hay que observar que la capacidad máxima sumada de todos los dispositivos no supere los 400 pF. El valor de los resistores de polarización no es muy crítico, y puede ir desde 1K8 (1.800 ohms) a 47K (47.000 ohms). Un valor menor de resistencia incrementa el consumo de los integrados pero disminuye la sensibilidad al ruido y mejora el tiempo de los flancos de subida y bajada de las señales. Los valores más comunes en uso son entre 1K8 y 10K.

Lo más común en los dispositivos para el bus I2C es que utilicen direcciones de 7 bits, aunque existen dispositivos de 10 bits. Este último caso es raro. Una dirección de 7 bits implica que se pueden poner hasta 128 dispositivos sobre un bus I2C, ya que un número de 7 bits puede ir desde 0 a 127. Cuando se envían las direcciones de 7 bit, de cualquier modo la transmisión es de 8 bits. El bit extra se utiliza para informarle al dispositivo esclavo si el dispositivo maestro va a escribir o va a leer datos desde él. Si el bit de lectura/escritura (R/W) es cero, el dispositivo maestro está escribiendo en el esclavo. Si el bit es 1 el maestro está leyendo desde el esclavo. La dirección de 7 bit se coloca en los 7 bits más significativos del byte y el bit de lectura/escritura es el bit menos significativo.

Direcciones de esclavos con 7,8 y 10 bits: http://www.totalphase.com/support/articles/200349176

Cada fabricante usa su propio direcionamiento para los esclavos, por ejemplo Philips: http://www.diolan.com/downloads/i2c-address-allocation-table.pdf

Cuando los datos son enviados por SDA, los pulsos de reloj son enviados por SCL para mantener el maestro y el esclavo sincronizados. Puesto que los datos son enviados como un bit en cada pulso de reloj, la transferencia de datos es un octavo la frecuencia de reloj. La frecuencia del reloj estándar originalmente se puso a 100 KHz y la mayoría de los integrados y microcontroladores soportan esta velocidad. En posteriores actualizaciones, se introdujo una fast speed de 400 KHz y una high speed de 1.7 a 3.4 MHz. Arduino puede soportar la velocidad estándar y fast speed, BeagleBoard tiene tres buses I2C cada uno a una velocidad distinta y tanto BeagleBoard como Raspberry Pi soportan velocidad estándar y fast speed. Fast speed corresponde a una velocidad de transferencia de 50Kbytes/sec lo que puede ser una velocidad muy baja para algunas aplicaciones de control. Una opción en ese caso es usar SPI en lugar de I2C.

Otra buena explicación de I2C: http://robots-argentina.com.ar/Comunicacion_busI2C.htm

Presentación de I2C por Philips: http://www.nxp.com/documents/application_note/AN10216.pdf

I2C en Arduino

La librería para manejar el bus I2C en Arduino es Wire: http://arduino.cc/en/reference/wire

Esta librería permite comunicar con I2C / TWI Arduino con otros dispositivos. En las placas Arduino con el diseño R3 (1.0 pinout), la SDA (línea de datos) y SCL (línea de reloj) están en los pines cerca del pin AREF.

El Arduino Due tiene dos interfaces I2C / TWI SDA1 y SCL1 que están cerca del pin AREF y los adicionales en los pines 20 y 21.

En el Arduino Uno los pines I2C son: A4 (SDA), A5 (SCL) y en el Mega son: 20 (SDA), 21 (SCL)

Funciones:

  • begin() – Inicia la librería Wire y especifica si es master o slave
  • requestFrom() – Usado por el maestro para solicitar datos del esclavo
  • beginTransmission() – Comenzar transmisión con esclavo.
  • endTransmission() – Finaliza la transmisión que comenzó con un esclavo y transmite los bytes en cola.
  • write() – Escribe datos desde un esclavo como respuesta a una petición del maestro o pone en cola la transmisión de un maestro.
  • available() – Devuelve el número de bytes para leer
  • read() – Lee un byte transmitido desde un esclavo a un maestro o viceversa
  • onReceive() – Llama a una función cuando un esclavo recibe una transmisión de un maestro.
  • onRequest() – Llama a una función cuando un maestro solicita datos de un maestro.

Presentaciones interesante de I2C en:

Y para profundizar más en el I2C en Arduino:

Un scanner I2C para ver los dispositivos en un bus:

También disponemos de controladores I2C en caso de no tener disponibles puertos I2C en el microcontrolador: http://www.nxp.com/documents/application_note/AN10148.pdf

Deja un comentario