
Introducción
En este tutorial, aprenderá todo sobre el Protocolo de comunicación I2C, por qué debería usarlo y cómo se implementa.

El Circuito Inter-Integrado (El protocolo I2C) es un protocolo destinado a permitir que múltiples circuitos integrados digitales «periféricos» ( «chips» ) se comuniquen con uno o más chips «controladores. Al igual que la interfaz periférica en serie ( SPI ), solo está destinada a comunicaciones de corta distancia dentro de un solo dispositivo. Al igual que las interfaces seriales asíncronas (como RS-232 o UART), solo requiere dos cables de señal para intercambiar información.
¿Por qué usar I2C?
Para averiguar por qué uno podría querer comunicarse sobre I2C, primero debe compararlo con las otras opciones disponibles para ver cómo difiere.
¿Qué tiene de malo el puerto serie UART?

Porque los puertos seriales son asíncrono (no se transmiten datos de reloj), los dispositivos que los usan deben acordar con anticipación una velocidad de datos. Los dos dispositivos también deben tener relojes que estén cerca de la misma velocidad y que lo sigan siendo; las diferencias excesivas entre las velocidades del reloj en cada extremo causarán datos confusos.
Los puertos seriales asíncronos requieren sobrecarga de hardware: el UART en cada extremo es relativamente complejo y difícil de implementar con precisión en el software si es necesario. Al menos un bit de inicio y parada es parte de cada cuadro de datos, lo que significa que se requieren 10 bits de tiempo de transmisión por cada 8 bits de datos enviados, que consume la tasa de datos.
Otra falla central en los puertos serie asíncronos es que son inherentemente adecuados para las comunicaciones entre dos y solo dos dispositivos. Mientras que conectar múltiples dispositivos a un solo puerto serie, (donde dos dispositivos intentan conducir la misma línea al mismo tiempo) siempre es un problema y deben tratarse cuidadosamente para evitar daños a los dispositivos en cuestión, generalmente a través de hardware externo.
Finalmente, la tasa de datos es un problema. Mientras que no hay teórico límite para las comunicaciones seriales asíncronas, la mayoría de los dispositivos UART solo admiten un cierto conjunto de velocidades de baudios fijas, y la más alta generalmente es de alrededor de 230400 bits por segundo.
¿Qué tiene de malo SPI?

El inconveniente más obvio de SPI es la cantidad de pines requeridos. Conectando un solo controlador a un solo periférico con un bus SPI se requieren cuatro líneas; cada dispositivo periférico adicional requiere un pin de E/S de chip adicional en el controlador. La rápida proliferación de conexiones de pin lo hace indeseable en situaciones en las que muchos dispositivos deben estar conectados a un solo controlador. Además, la gran cantidad de conexiones para cada dispositivo puede dificultar las señales de enrutamiento en situaciones de diseño de PCB ajustadas.
SPI solo permite un controlador en el bus, pero admite un número arbitrario de periféricos (sujetos solo a la capacidad de conducción de los dispositivos conectados al bus y al número de pines de selección de chip disponibles).
SPI es bueno para conexiones con una alta tasa de transferencia de datos dúplex completo (envío y recepción simultáneos de datos), ya que admite velocidades de reloj superiores a 10MHz (10 millones de bits por segundo) para algunos dispositivos, y la velocidad se escala muy bien. El hardware en cada extremo suele ser un registro de cambio muy simple, lo que permite una fácil implementación en el software.
Hablemos de I2C – ¡Lo mejor de ambos mundos!

I2C requiere solo dos cables, como la comunicación serie asíncrona, pero esos dos cables pueden admitir hasta 1008 dispositivos periféricos. Además, a diferencia de SPI, el I2C puede admitir un sistema multicontrolador, permitiendo más de un controlador para comunicarse con todos los dispositivos periféricos en el bus (aunque los dispositivos controladores no pueden hablar entre sí a través del bus y deben turnarse usando las líneas de bus).
Las tasas de datos caen entre serie asíncrona y SPI; la mayoría de los dispositivos I2C pueden comunicarse a 100kHz o 400kHz. Hay algunos gastos generales con I2C; por cada 8 bits de datos que se enviarán, se debe transmitir un bit adicional de metadatos (el bit «ACK / NACK», que discutiremos más adelante).
El hardware requerido para implementar I2C es más complejo que SPI, pero menos que el hardware serial asíncrono. Se puede implementar de manera bastante trivial en software.
Nota: Puede estar familiarizado con los términos «maestro» y «esclavo» para representar la relación entre dispositivos en un Bus I2C. Los términos se consideran obsoletos y ahora se reemplazan con los términos «controlador» y «periférico«, respectivamente.
Nombre obsoleto | Nombre de reemplazo |
---|---|
Maestro | Controlador |
Esclavo | Periférico |
La convención de nombres puede variar según el fabricante, el lenguaje de programación, las empresas u organizaciones (ej: principal/secundario, iniciador-respondedor, fuente/réplica, etc. ). Para obtener más información, consulte los siguientes enlaces.
- Wikipedia: preocupaciones terminológicas
- OSHWA: una resolución para redefinir los nombres de señal SPI
Una breve historia de I2C
I2C fue desarrollado originalmente en 1982 por Philips para varios chips de Philips. La especificación original permitía solo comunicaciones de 100 kHz y solo proporcionaba direcciones de 7 bits, lo que limitaba el número de dispositivos en el bus a 112 (hay varias direcciones reservadas, que nunca se usarán). En 1992, se publicó la primera especificación pública, agregando un modo rápido de 400 kHz, así como un espacio de direcciones expandido de 10 bits. Desde entonces se han incorporado por ejemplo, en dispositivos ATMega328 y en muchas placas compatibles con Arduino un soporte para dispositivos I2C con tres modos adicionales:
- modo rápido más, a 1MHz
- modo de alta velocidad, a 3.4MHz
- modo ultrarrápido, a 5MHz
Además de I2C, Intel introdujo una variante en 1995 llamada Bus de gestión del sistema (SMBus). El SMBus es un formato más estrictamente controlado, destinado a maximizar la previsibilidad de las comunicaciones entre los circuitos integrados de soporte en las placas base de la PC. La diferencia más significativa entre SMBus es que limita las velocidades de 10kHz a 100kHz, mientras que I2C puede admitir dispositivos de 0kHz a 5MHz. SMBus incluye un modo de tiempo de espera de reloj que hace que las operaciones de baja velocidad sean ilegales, aunque muchos dispositivos SMBus lo admitirán de todos modos para maximizar la interoperabilidad con sistemas embebidos e I2C.
I2C en el nivel de hardware
Señales
El bus I2C consta de dos señales: SDA y SCL. SDA (Los datos en serie) son la señal de datos y SCL (Reloj en serie) es la señal del reloj. La señal del reloj siempre es generada por el controlador de bus actual; algunos dispositivos periféricos pueden obligar al reloj a veces a retrasar el envío del controlador de más datos (o requerir más tiempo para preparar datos antes de que el controlador intente marcarlo). Esto se llama «estiramiento del reloj» y se describe en la página del protocolo.
A diferencia de las conexiones UART o SPI, los conductores del bus I2C son «drenaje abierto», lo que significa que pueden bajar la línea de señal correspondiente, pero no pueden conducirla a alto. Por lo tanto, no puede haber contención en el bus donde un dispositivo está tratando de conducir la línea hacia alto mientras otro intenta bajarla, eliminando el potencial de daño a los conductores o la disipación excesiva de energía en el sistema. Cada línea de señal tiene una resistencia PULL-UP para restaurar la señal a alto cuando ningún dispositivo la está afirmando a bajo.

Observe las dos resistencias pull-up en las dos líneas de comunicación.
La selección de resistencia varía con los dispositivos en el bus, pero una buena regla general es comenzar con una resistencia de 4.7kohm y ajustar si fuera necesario. I2C es un protocolo bastante robusto y se puede usar con tiradas cortas de alambre (2-3m). Para ejecuciones largas, o sistemas con muchos dispositivos, las resistencias más pequeñas son mejores.

Los dispositivos I2C generalmente incluyen resistencias pull-up para los pines SCL y SDA. Si tienes muchos dispositivos I2C en el mismo bus, es posible que debas ajustar el valor equivalente para las resistencias pull-up desconectando las resistencias pull-up en algunos de los dispositivos.
Niveles lógicos de señal
Como los dispositivos en el bus en realidad no manejan las señales alto, I2C permite cierta flexibilidad en la conexión de dispositivos con diferentes voltajes de E/S. En general, en un sistema donde un dispositivo tiene un voltaje más alto que otro, es posible conectar los dos dispositivos a través de I2C sin ningún circuito de cambio de nivel entre ellos. El truco es conectar las resistencias pull-up a la parte inferior de los dos voltajes. Esto solo funciona en algunos casos, donde la parte inferior de los dos voltajes del sistema excede el voltaje de entrada de alto nivel del sistema de voltaje más alto, por ejemplo, un Arduino de 5V y un acelerómetro de 3.3V. Dependiendo del diseño del Arduino o el dispositivo I2C, recomendamos usar un convertidor de nivel lógico para que sea consistente y evite dañar cualquier dispositivo en el bus.
Si la diferencia de voltaje entre los dos sistemas es demasiado grande (digamos, 5V y 2.5V), en ADICHIP ofrecemos un Adaptador de cambios de nivel para I2C.
Otros productos:
-
Lector De Huellas Dactilares Uart Stm32f205$48.672,48
-
Dht11 Sensor De Humedad Relativa Y Temperatura Dht11 Arduino$3.288,06
-
Sonda Digital Temperatura Ds18b20 Arduino Pic Avr 18b20$5.966,47
-
Easypic Fusion V7 Empty Mcucard Eth Tqfp Pt Id:1293$25.186,70
-
Reloj De Tiempo Real 1wire Rtc4 Click 1 Wire 1-wire$16.647,60
-
Sensor De Temperatura Thermo 3 Click$26.910,83
-
Convertidor Lógico Txb0108 Bidireccional 8ch Adafruit Id:395$26.495,28
-
Módulo Humedad Temperatura Hdc1000$41.743,37
Protocolo
La comunicación a través de I2C es más compleja que una solución UART o SPI. La señalización debe cumplir con un cierto protocolo para que los dispositivos en el bus lo reconozcan como válido. Afortunadamente, la mayoría de los dispositivos implementan el protocolo y ellos mismos se ocupan de todos los detalles complicados, lo que le permite concentrarse en los datos que desea intercambiar.
Conceptos básicos
Los mensajes se dividen en dos tipos de cuadros: un marco de dirección, donde el controlador indica el periférico al que se envía el mensaje, y uno o más marcos de datos, que son mensajes de datos de 8 bits pasados del controlador al periférico o viceversa. Los datos se colocan en la línea SDA después de que SCL baja, y se muestrean después de que la línea SCL se eleva. El tiempo entre el borde del reloj y la lectura/escritura de datos está definido por los dispositivos en el bus y variará de un chip a otro.

Haga clic en la imagen para obtener una vista más cercana.
Condición de inicio
Para iniciar el marco de la dirección, el dispositivo controlador deja SCL alto y tira SDA bajo. Esto pone a todos los dispositivos periféricos en aviso de que una transmisión está a punto de comenzar. Si dos controladores desean tomar posesión del bus al mismo tiempo, cualquier dispositivo que reduzca el SDA primero gana la carrera y gana el control del bus. Es posible emitir inicios repetidos, iniciando una nueva secuencia de comunicación sin ceder el control del bus a otro controlador; hablaremos de eso más tarde.
Marco de direcciones
El marco de la dirección siempre es el primero en cualquier secuencia de comunicación nueva. Para una dirección de 7 bits, la dirección se registra primero en el bit más significativo (MSB), seguido de un bit R/W que indica si se trata de una operación de lectura (1) o escritura (0).
El noveno bit del cuadro es el bit NACK/ACK. Este es el caso de todos los cuadros (datos o dirección). Una vez que se envían los primeros 8 bits del marco, el dispositivo receptor tiene control sobre SDA. Si el dispositivo receptor no baja la línea SDA antes del pulso del noveno reloj, se puede inferir que el dispositivo receptor no recibió los datos o no sabía cómo analizar el mensaje. En ese caso, el intercambio se detiene, y depende del controlador del sistema decidir cómo proceder.
Marcos de datos
Después de enviar el marco de la dirección, los datos pueden comenzar a transmitirse. El controlador simplemente continuará generando pulsos de reloj en un intervalo regular, y los datos serán colocados en SDA por el controlador o el periférico, dependiendo de si el bit R/W indicó una operación de lectura o escritura. El número de cuadros de datos es arbitrario, y la mayoría de los dispositivos periféricos aumentarán automáticamente el registro interno, lo que significa que las lecturas o escrituras posteriores vendrán del próximo registro en línea.
Condición de Stop
Una vez que se hayan enviado todos los marcos de datos, el controlador generará una condición de detención. Las condiciones de detención se definen mediante una transición de 0-> 1 (baja a alta) en SDA después una transición de 0-> 1 en SCL, con SCL restante alto. Durante la operación normal de redacción de datos, el valor en SDA NO debe cambiar cuando la SCL es alta, para evitar condiciones de detención falsas.
Temas de protocolo avanzado
Direcciones de 10 bits
En un sistema de direccionamiento de 10 bits, se requieren dos cuadros para transmitir la dirección periférica. El primer cuadro consistirá en el código b11110xyz, donde ‘x’ es el MSB de la dirección periférica, y es el bit 8 de la dirección periférica, y z es el bit lectura/escritura como se describió anteriormente. El bit ACK del primer cuadro será afirmado por todos los periféricos que coincidan con los dos primeros bits de la dirección.

Haga clic en la imagen para obtener una vista más cercana.
Al igual que con una transferencia normal de 7 bits, otra transferencia comienza de inmediato, y esta transferencia contiene los bits 7:0 de la dirección. En este punto, el periférico abordado debe responder con un bit ACK. Si no es así, el modo de falla es el mismo que un sistema de 7 bits.
Tenga en cuenta que los dispositivos de dirección de 10 bits pueden coexistir con dispositivos de dirección de 7 bits, ya que la parte principal ‘11110’ de la dirección no forma parte de ninguna dirección válida de 7 bits.
Condiciones de inicio repetidas
A veces, es importante que se permita a un controlador intercambiar varios mensajes de una vez, sin permitir que otros controladores en el autobús interfieran. Por esta razón, se ha definido la condición de inicio repetido.

Para realizar un inicio repetido, se permite que SDA suba mientras que SCL es bajo, se permite que SCL suba y luego SDA se vuelve a bajar mientras SCL es alto. Debido a que no había una condición de parada en el bus, la comunicación anterior no se completó realmente y el controlador actual mantiene el control del bus.
En este punto, el siguiente mensaje puede comenzar la transmisión. La sintaxis de este nuevo mensaje es la misma que cualquier otro mensaje: un marco de dirección seguido de marcos de datos. Se permite cualquier cantidad de arranques repetidos, y el controlador mantendrá el control del bus hasta que emita una condición de parada.
Estiramiento del reloj
A veces, la velocidad de datos del controlador excederá la capacidad del periférico para proporcionar esos datos. Esto puede deberse a que los datos aún no están listos (por ejemplo, el periférico aún no ha completado una conversión de analógico a digital) o porque una operación anterior aún no se ha completado (por ej, una EEPROM que aún no ha completado la escritura en memoria no volátil y necesita terminar eso antes de que pueda atender otras solicitudes).

En este caso, algunos dispositivos periféricos ejecutarán lo que se conoce como «estiramiento del reloj». Nominalmente, todo el reloj es impulsado por los periféricos del controlador — simplemente coloque datos en el bus o saque los datos del bus en respuesta a los pulsos del reloj del controlador. En cualquier momento del proceso de transferencia de datos, un periférico dirigido puede mantener baja la línea SCL después de que el controlador la libere. Se requiere que el controlador se abstenga de pulsos de reloj adicionales o transferencia de datos hasta el momento en que el periférico libere la línea SCL.
Recursos
- Wikipedia Artículo sobre I2C – No es genial, pero no es un lugar para comenzar.
- Doc de normas – Phillips Semiconductor se convirtió en NXP hace unos años; este es el documento oficial de estándares para I2C.
- I2C imprimación – La cartilla oficial en I2C y tecnologías relacionadas.
- Herramientas de Linux para I2C – Un buen conjunto de herramientas para trabajar con I2C y autobuses relacionados en entornos Linux integrados, como pcDuino o Raspberry Pi.
- Asociación de hardware de código abierto: una resolución para redefinir los nombres de señal SPI