INTRODUCCIÓN AL I2C.

INTRODUCCIÓN AL I2C-BUS.

Hablar del I²C bus, en nuestros días es, poco menos que arriesgado, hay que afinar mucho en lo que se dice, ya que cualquiera ha realizado su descripción y creo realmente que hay muy buenas descripciones y de esas, se bebe el conocimiento, por parte de muchos aficionados a la electrónica, cuando tiene que utilizar esta técnica de transmisión de datos como es el I²C-bus. I²C es un acrónimo de “Inter-Integrated Circuit”. En esta ocasión, espero exponer mi puntual experiencia y dar un poco de luz a los que estén interesados en conocer los pasos a seguir para utilizar con éxito esta técnica de transmisión I²C.

Hace ya muchos años cuando tuve conocimiento del sistema I2C bus, en aquellos momentos mi trabajo estaba relacionado directamente con la electrónica más puntera de la época, lo que se conocía como, “la cresta de la ola”. Ciertamente que no estaba en mi camino el hacer prácticas (por motivos que no vienen al caso) de esta novedosa técnica que, presentó a principios de los ’90, la firma “Philips Semiconductors” (ahora NXP), sin embargo, si puse en manos de bastantes ingenieros de la época y las Universidades de la zona, la extensa información que proveía la mencionada empresa.

Los ingenieros de “Philips” vieron la necesidad de la simplificación y normalización de las líneas de datos que viajan entre los diversos circuitos integrados en sus productos. Su solución fue el bus I2C. Esto redujo un gran número de cables a sólo dos (SDA = datos, y SCL = reloj).

Esta documentación, nace sabiendo que existen otras muchas más profundas, solamente pretende explicar desde mi punto de vista, que es, y como se comporta superficialmente una red I2C, por si alguien necesita un detalle diferente. Se supone, que usted, domina el sistema binario, decimal codificado y hexadecimal, esto le servirá para una mejor comprensión.

UN MOTIVO PARA USAR EL I2C.

Es sabido que el llamado “playgrund” de Arduino tiene una descripción sobre el I²C – TWI (Two-Wire Interface), se trata del I²C. En dicho documento, se habla del I²C y se refiere a enlaces relevantes, para los que tengan interés en el tema.

Por mi parte, he de decir que, hasta hace algún tiempo, no había puesto ningún empeño en ampliar mis conocimientos sobre la transmisión de datos, tal vez por que no había tenido la necesidad. Sin embargo hace poco más de un año cuando empecé a utilizar en mis ratos libres, Arduino. Descubrí que disponía de dos patillas que están dotadas de este protocolo o sistema de transmisión y bueno, mi interés no paso de la curiosidad del momento, por lo que no entre en detalle.

Por aquellos días, tuve un encuentro casual con un amigo que, me propuso realizar un sistema de acceso a una empresa. En el proyecto por denominarlo de algún modo, se debía controlar los vehículos que entraban y salían de la empresa, por puertas de entrada y salida, el sistema debía enviar datos a un PC central, en el cual se encuentran los permisos de los vehículos autorizados… En cierto momento del proyecto, se presentó la necesidad de utilizar el sistema del bus I2C, para economizar en las E/S del Arduino y ese es el momento en el que surge la necesidad de conocer más a fondo el modo en que se basa y como trabaja el mencionado protocolo.

Mis primeros paso fueron la adquisición de datos; aquellos libros de Philips que guarde, ahora serían vitales, además de información que, extraje de varios documentos de dominio público que, se encuentran en la red y otros libros actuales que lo relacionan con Arduino, aunque aquí, quiero hablar del I2C en general.

Entre la documentación de TWI (Two-Wire Interface) que es incompleta, por que no explica cada función, como corresponde a una función I²C, los ejemplos de código que son anticuados y de vez en cuando incorrectos, mi carencia de familiaridad con I²C en general, además, no teniendo un circuito I²C en funcionamiento como referencia y desde luego mis despistes y mis muchos errores, esto puso por un momento a relucir una falta de experiencia desconcertante por mi parte. Esto fue un reto.

Después, me procuré una serie de circuitos integrados que tuvieran este protocolo entre sus cualidades, encontré bastantes dispositivos basados en este protocolo del I²C y ya sólo tenía que poner manos a la obra, practicar y practicar, buscar la forma de servirme de aquellas posibilidades y adaptarlas a mis necesidades. No pasó mucho tiempo para obtener el éxito esperado, al principio estuvo el tema de direccionar cada dispositivo, todos los dispositivos diseñados para funcionar en este bus poseen su propia y única dirección de acceso, preestablecida por el fabricante.

Poder leer una dirección, ni que decir, de escribir en una dirección, recomiendo leer las HD del fabricante para conocer dicha dirección. Esto para mi ya pasó, con esto quiero decir a los interesados que, no es tan difícil aprender y aplicar el protocolo del bus I²C.

QUÉ ES EL I²C-BUS.

El I²C bus, no tan sólo son dos cables, usados para realizar una transmisión bidireccional de datos entre distintos sistemas gobernados por microcontroladores de forma eficaz. Veremos, cómo podemos controlar un importante número de dispositivos con nuestro micro (Arduino), aunque, al principio no es fácil de dominar.

Se trata de, un bus bidireccional que utiliza dos líneas, una de datos serie (SDA) y otra de reloj serie (SCL), que requiere resistencias de polarización a positivo (RPA). SCL es la línea de reloj, se utiliza para sincronizar todos los datos SDA de las transferencias durante I²C bus. SDA es la línea de datos.

Las líneas SCL y SDA están conectadas a todos los dispositivos en el I²C bus. Ambas líneas SCL y SDA son del tipo drenador abierto asociados a un transistor de efecto de campo (o FET), es decir, un estado similar al de colector abierto. Esto significa que el chip puede manejar su salida a BAJO, pero no puede manejar a ALTO. Para que la línea pueda ir a ALTO, se deben proporcionar resistencias de polarización a 5V. Necesita de una resistencia de la línea SCL a la línea de 5V y otra de la línea SDA a la línea de 5V.

Sólo necesita un conjunto de resistencias de RPA (pull-up) para todo el I²C bus. Cuidado, no son necesarias para cada dispositivo. La alimentación del sistema, debe tener una masa común, también puede haber una alimentación compartida que, se distribuye entre los distintos dispositivos.

Los dispositivos en el I²C bus son maestros o esclavos. El maestro, es siempre el dispositivo que maneja la línea de reloj SCL. Los esclavos, son los dispositivos que responden al maestro. Un esclavo no puede iniciar una transferencia a través del I²C bus, sólo un maestro puede hacer esa función. Generalmente son, varios esclavos en el I²C bus, sin embargo, normalmente hay un solo maestro. Es posible tener varios maestros, pero es inusual y no se comentará aquí. Por lo tanto, LOS ESCLAVOS, nunca inician una transferencia. Tanto el maestro, como el esclavo puede transferir datos a través del I²C bus, pero la transferencia siempre es controlada por el maestro.

 i2caFig. 1

Todas las direcciones I²C bus son de 7 bits o 10 bits. Esto significa que, se pueden tener hasta 128 dispositivos en el bus I²C, ya que un número de 7bit puede estar entre 0 y 127. El I²C tiene un diseño de espacio de referencia de 7 bits de direcciones, reservado con 16 direcciones, de modo que finalmente, pueden comunicarse en el mismo bus un máximo de 112 nodos. El número máximo de nodos está limitado por el espacio de direcciones y también por la capacidad total de los buses de 400 pF, lo que restringe la práctica de comunicación, a distancias de unos pocos metros.

Cuando se envía la dirección de 7 bits, siempre seguimos enviando 8 bits. El bit extra (bit 8) se usa para informar al esclavo si el maestro está escribiendo o leyendo de él. Si el bit 8º es 0, el maestro está escribiendo en el esclavo. Si el bit 8º es 1, el maestro esta en modo lectura del esclavo. Existen disposiciones en la norma de I²C para entornos multi-master, así como de 10 bits frente a la más simple y la más comúnmente usada, es la configuración de un solo maestro, de 7 bits de direccionamiento.

Yo se que, la localización de la dirección de 7 bits en la parte superior del byte, es una fuente de confusión para los recién iniciados, pero intentaré hacer un esfuerzo para dejar lo más claro posible este punto. No debería haber ningún problema en que, los tres bits A0, A1 y A2 correspondientes a los pines 1, 2 y 3 son los que, seleccionan la dirección del dispositivo, del P0 al P7 son los puertos de E/S e INT, es una salida de interrupción que no lo usaremos. De modo que, para poner en servicio un PDF8574, son necesarias dos cosas, la dirección del dispositivo (b0100000) y un byte de datos para el pin de salida que se necesita. Veamos la tabla que sigue:

definicion_interfaceFig. 2

De modo que, si ponemos los pines A0 ~ A2 a masa o GND, la dirección de nuestro dispositivo en el sistema binario será 0100000, o sea, 0x20 en formato hexadecimal. Y con los bytes de datos, haremos lo mismo, configurando así, los pines de salida, por ejemplo: si queremos poner todos a Alto (H), enviamos 0 en binario que, en hexadecimal es 0, o bien para poner los cuatro primeros a H (alto) y los segundos cuatro a L (bajo). Se utiliza 00001111 en binario que, en hexadecimal es 0x0F.

¿Se ha dado cuenta? Por qué razón estos datos parecen estar al revés de lo que se ha comentado.
Y ¿por qué enviamos un cero, convirtiendo todos los pines a H? El motivo es, que las E/S del PCH8574 son sumideros de corriente, esto quiere decir que, las corrientes circulan desde los +5V, a través de las cargas hacia los pines de E/S del dispositivo. No olvidemos que estamos configurando los datos del segundo byte y siguientes. Tratamos con las entradas/salidas. Por dicho motivo, los valores de E/S que establezcamos, se veran complementados en nuestra instrucción.

Además, en la instrucción, no hay que olvidar el bit0 (R/W), el de menor peso LSB (o Least Significant Bit, en inglés) que le indica al bus I2C, la función del maestro, según su valor (0 para leer y 1 para escribir).

Por ejemplo, para escribir en la dirección 0x21, realmente se tiene que enviar 0x42, que es el 21 desplazado 1 bit a la izquierda, para insertar el bit de lectura/escritura (R/W) en el byte (recuerde 8bits). Veamos:

    Bit 76543210
    b 00100001 = 21 h; b00100001 x 10 = b01000010;
    b 01000010 = 42 h

Si usted, desea comprender mejor como se direcciona un dispositivo que utiliza el protocolo I2C, como el PCF8574, le recomiendo que lea mi artículo en esta dirección, donde se describe con más profundidad.

EL PROTOCOLO.

La base del protocolo I²C-bus es que, el bus tiene dos funciones para los nodos: maestro y esclavo. El resultado de este sistema produce un anillo compuesto por dos vías (hilos) para el desarrollo de la función de comunicarse entre sí los dispositivos interconectados a las mencionadas vías, esto permite comunicarse entre ellos mismos con un protocolo que, consiste en que, en cada momento hay un MAESTRO y el resto son ESCLAVOS. Un símil sería que, –mientras uno habla, el resto escuchan-, o también, uno escribe y el resto leen. Observe con atención la figura que sigue.

transferenciai2cFig. 3

En la figura anterior se puede apreciar que, la condición START está definida, cuando la señal de reloj SCL permanece estable ALTO (H) además, el nivel de la señal de “no reconocimiento”, debe ser también ALTA (H), si en ese preciso instante se produce un descenso (flanco de bajada) en la señal de datos, automáticamente se produce la condición de START (inicio) de la transmisión y el dispositivo que la produjo, se convierte en MAESTRO, dando comienzo la transmisión. El pulso de reconocer o reconocimiento, conocido como ACK (del inglés Acknowledge), se logra colocando la línea de datos a un nivel lógico bajo, durante el transcurso del noveno pulso de reloj.

Ya se que, esta parte, es mas compleja de lo que parece. Es muy importante, debe observar con atención, los cuatro pasos que sigue el inicio de una transmisión, son los 4 bytes de inicio, la figura que sigue le ayudará a comprender.

 transfer1Fig. 4

  1. En el primer paso, el byte que se envía es START, después de la condición de Bit inicio (START) se envía un byte que, contiene siete bits que componen la dirección del dispositivo que se quiere seleccionar y un octavo bit R/W (que corresponde a la operación que se quiere realizar en él, lectura o escritura).
  2. El segundo paso, este byte, contiene la dirección del registro que se desea leer/escribir. Puede realizarse un reinicio como se muestra en la figura.
  3. El tercer paso, aquí se escribe la dirección con el bit menos significativo LSB a nivel 1, para indicar que se lee.
  4. El cuarto paso y siguientes continúan la misma función de lectura, no tiene por qué ser sólo uno.

A, cada byte transferido al bus, le sigue un noveno pulso de reloj durante el cual, el dispositivo receptor, debe generar un pulso de reconocimiento A.

Para pasar a la función de escritura en el mismo dispositivo, puede realizarse, enviando un bit de STOP o de reinicio, considerado como parada e inicio. El paso que sigue es, escribir el byte que contiene siete bits que componen la dirección del dispositivo que se quiere seleccionar y un octavo bit a 0 que corresponde a la operación que se quiere realizar con él, ahora escritura. Y los pasos siguientes pueden ser como en el caso anterior.

figura28Fig. 5

En la imagen: S (start), le sigue [primer byte] la dirección (11110XX)+ (R/W) 0 (para escribir) y A (acknowledge) y [2º byte]+ A. El tercer byte son los datos, seguido de A, de este modo sigue la transmisión, hasta que realizamos un reinicio o nuevo Start, en ese momento, se envía de nuevo la dirección y puede enviarse un octavo bit a 1, para leer del dispositivo esclavo (segunda línea, de la figura) y sigue hasta el final de la transmisión. Realmente son 10 bits los emitidos en el primer envío, para comunicarse con cualquier esclavo.

Dicho esto, se debe resaltar que en el I2C-bus, se definen tres tipos básicos de mensajes, cada uno de los cuales comienza con un START y se termina con una STOP.

    a) Simple mensaje, donde un maestro escribe datos a un esclavo.
    b) Simple mensaje, donde un maestro lee datos de un esclavo.
    C) Mensajes combinados, donde un maestro publica y al menos dos leen/escriben a uno o varios esclavos.

En un mensaje combinado, cada uno, sea de lectura o escritura, comienza con un START y la dirección de esclavo. Después del primer START, también se pueden hacer llamados repetidos bits de START, esto confirma que repetidos bits START no vienen precedidos por bits de STOP, que es como los esclavos conocen la próxima transferencia que, es parte del mismo mensaje. Todo esclavo puede sólo responder a mensajes particulares, tal como se define por su documentación de producto.

Cuando el maestro ha terminado de escribir todos los datos en el esclavo, se envía una secuencia de parada que completa la transacción. Así que para escribir en un dispositivo esclavo:

    1. Enviar una secuencia de inicio (START).
    2. Enviar la dirección I2C del esclavo más el bit bajo R/W. (0xC0 = b1100 0000)
    3. Enviar el número de registro interno al que se quiere escribir. (ej. 0x00 = b0000 0000)
    4. Enviar el byte de datos. (0x01 = b 0000 0001)
    5. [Opcionalmente, envíe algunos otros bytes de datos].
    6. Enviar la secuencia de parada (STOP).

Para lograr este propósito, se parte de una palabra de dirección, un byte, en los que debemos distinguir: el bit START, con dirección del esclavo al que interrogará. Esta dirección está formada por 4 bits de código de control más tres bits (A0..A2) de selección de dispositivo y el bit de escritura/lectura (R/W), por último se envía el bit ACK (reconocer) por que es el maestro el que está transmitiendo.

device_addressingFig. 6

FUNCIÓN ESCRITURA.

Cuando un dispositivo quiere “decir algo” se dirige al dispositivo con el que quiere hablar, envía una señal START (inicio) condicional y se procede al envío de un byte con los siete bits que componen la dirección del dispositivo esclavo con el que se quiere comunicar, mas un octavo bit de menor peso que corresponde con la operación deseada (E/L), escritura = 0 (enviar al esclavo) y lectura = 1 (recibir del esclavo), seguido del bit reconocer ACK.

La dirección enviada es comparada por cada uno de los esclavos del bus con su propia dirección, si ambas coinciden, el esclavo se considera direccionado como esclavo-receptor o esclavo-transmisor dependiendo del bit de menor peso E/L. El esclavo responde enviando un bit de reconocer ACK que le indica al dispositivo maestro que el esclavo reconoce la solicitud y están en condiciones de comunicarse. Y comienza el intercambio de información entre ambos dispositivos.

El maestro envía la dirección del registro interno del dispositivo, en el que se desea leer o escribir, el esclavo responde con otro bit de reconocer, ahora el maestro puede empezar a leer o escribir bytes de datos. Todos los bytes de datos deben constar de 8 bits, el número máximo de bytes que pueden ser enviados en una transmisión no está restringido, siendo el esclavo quien fija esta cantidad dependiendo de sus características. Esto se consigue por que cada byte leído/escrito por el maestro debe ser obligatoriamente reconocido por un bit de reconocer por el dispositivo maestro/esclavo.

Es conveniente recordar estos puntos que, el número de bytes de datos transferidos entre las condiciones de inicio y parada del transmisor al receptor no esta limitado. Cada byte de ocho bits es seguido por un bit reconocer (ver Fig. 6, abajo). El bit reconocer es un nivel ALTO puesto en el bus por el transmisor mientras que el maestro genera un pulso de reloj extra reconocer relacionado.

Un receptor esclavo cuando es direccionado debe generar un bit reconocer después de la recepción de cada byte. También un maestro debe generar un bit reconocer después de la recepción de cada byte que ha sido registrado desde el esclavo transmisor. El dispositivo que reconoce tiene que poner a BAJO la línea SDA durante el pulso de reloj reconocer, por lo que la línea SDA es estable BAJO, durante el período ALTO del pulso de reloj reconocer relacionado, los tiempos de configuración y mantenimiento deben ser tenidos en cuenta.

A pesar de que el maestro normalmente controla el estado de la línea de reloj SCL , puede que un esclavo de baja velocidad o que un esclavo deba detener la transferencia de datos mientras efectúa otra función, podría forzar la línea SCL a nivel bajo. Esto haría que el maestro entrase en un estado de espera, durante el cual, no transmitiría información esperando a que el esclavo esté listo para continuar la transferencia en el punto donde había sido detenida. Cuando finaliza la comunicación, el maestro transmite una condición de “stop” para dejar libre el bus.

figura-6-escrituraFig. 7

FUNCIÓN LECTURA.

La figura que sigue, corresponde al registro en el modo lectura. Siga las señales de la figura para comprender su funcionamiento.

figura-8-lecturaFig. 8

Esto es para comunicaciones simples I²C casi todo, pero hay una complicación más. Cuando el maestro lee del esclavo, es el esclavo el que coloca los datos sobre la línea SDA, pero es el maestro quien controla el reloj. ¿Qué pasa si el esclavo no está listo para enviar los datos? Con dispositivos tales como memorias EEPROM esto no es un problema, pero cuando el dispositivo esclavo es en realidad un microprocesador con otras cosas que hacer, puede ser un problema.

El microprocesador del dispositivo esclavo tendrá que ir a una rutina de interrupción, guardará sus registros de trabajo, averiguará de que dirección quiere leer el maestro, para obtener los datos y colocarlos en su registro de transmisión. Esto puede tomar muchos uS para que ocurra, mientras que el maestro está felizmente enviando pulsos de reloj por la línea SCL que, el esclavo no puede responder.

El protocolo I²C proporciona una solución a esto: el esclavo está autorizado a mantener la línea SCL baja. Esto se llama estiramiento de reloj. Cuando el esclavo recibe la orden de lectura del maestro, éste mantiene la línea de reloj baja. El microprocesador obtiene los datos solicitados, los coloca en el registro de transmisión y libera la línea de reloj que habilita la resistencia RPA para finalmente dejarla a alto.

Desde el punto de vista de los maestros, se emitirá el primer pulso de reloj de lectura, haciendo SCL ALTO y luego verificará si realmente se ha ido a ALTO. Si es todavía BAJO, entonces es el esclavo quien lo mantendrá BAJO y el maestro deberá  esperar hasta que este vaya a ALTO antes de continuar. Por suerte, los puertos de hardware I2C en la mayoría de los microprocesadores se encargará de forma automática.

Mi experiencia personal en el uso del I2C bus, evidentemente debe mejorar con la práctica, del mismo modo que ocurrirá con la del lector interesado, si sigue realizando proyectos y practicando con el sistema de transmisión de datos entre dispositivos con microcontroladores. La práctica ha ido mejorando mis conocimientos sobre el I2C y algunas muestras se encuentran en este sitio. Para una mayor información refiérase a las indicaciones del fabricante enespecificaciones del I2C de Philips.

EL I²C-BUS CON ARDUINO.

Actualmente existen muchas aplicaciones, para aplicar con la placa Arduino; como un reloj en tiempo real, potenciómetros digitales, sensores de temperatura, brújulas digitales, chips de memoria, servos, circuitos de radio FM, E/S expansores, controladores de LCD, amplificadores, etc. Y además usted puede tener más de una idea para aplicar este bus, en cualquier momento, como se ha dicho, el número máximo de dispositivos I²C utiliza en un momento dado es de 112.

Debe tenerse muy en cuenta el Arduino que está utilizando, si es un Arduino Mega, el pin SDA, es pin 20 y el SCL, es el pin 21, así que, tenga en cuenta que en los escudos con I²C, necesitan ser específicamente para el Mega. Si usted tiene otro tipo de tarjeta, revise la hoja de datos o consulte la página web de pruebas de hardware de Arduino. Y por último, si usted está usando un microcontrolador ATMega328 base DIP-PU, deberá utilizar para SDA el pin 27 y el pin 28 para SCL.

Si sólo está utilizando un dispositivo I²C, las resistencias RPA, no son necesarias ya que el microcontrolador ATMega328 en nuestro Arduino las ha incorporado Sin embargo, si está empleando una serie de dispositivos utilice dos resistencias de 10k ohmios. Como todo, algunas pruebas en un circuito protoboard o prototipo determinará su necesidad. La longitud máxima de un bus I²C es de alrededor de un metro y es una función de la capacidad del bus. Esta distancia se puede ampliar con el uso de un circuito especial que no examinaremos en el presente trabajo.

Cada dispositivo se puede conectar al bus en cualquier orden y, como ya se ha mencionado, los dispositivos pueden ser maestros o esclavos. En nuestra aplicación el IDE Arduino, es el maestro y los dispositivos que “colguemos” en el bus I²C son los esclavos. Podemos escribir datos en un dispositivo o leer datos de un dispositivo. A estas alturas ya debe estar pensando “¿cómo podemos diferenciar cada dispositivo en el bus?” Más arriba, de modo general, ya se ha documentado. Decíamos que, cada dispositivo tiene una dirección única. Usaremos esa dirección, en las funciones descritas más adelante para dirigir nuestras peticiones de lectura o escritura al dispositivo correcto.

Al igual que en la mayoría de dispositivos, haremos uso de una librería para Arduino, en este caso <wire.h>. A continuación, utilizamos la function Wire.begin();dentro de la configuración del void setup() y estaremos listos para empezar.

Envío de datos (sending), desde nuestro Arduino a los dispositivos I²C depende de dos cosas: la dirección única del dispositivo (que necesitamos esté en hexadecimal) y al menos un byte de datos a enviar. (Como ya se ha descrito arriba).

Por ejemplo; la dirección del dispositivo en el ejemplo (de abajo) es 01101000 (binario), que es 0x68 en hexadecimal.

Entonces, debemos establecer el valor del puntero, que es un valor entre 0 y 127, o sea 0×00 y 0x7F en hexadecimal. Así que para establecer el puntero a cero, usaríamos las funciones siguientes:

    Wire.beginTransmission(0x68); // dirección única 0x68 del ds1307 o 01101000b

Esto envía la dirección del dispositivo por la línea del bus SDA (datos). Viaja a lo largo del bus, y “avisa” al dispositivo correspondiente que tiene algunos datos que vienen …

    Wire.send(0x00); // inicia el puntero de la memoria del ds1307 (es el byte)

Esto envía el byte de datos en el dispositivo – en el registro del dispositivo (o la memoria de todo tipo), que está esperando datos, con los ‘brazos abiertos’. Cualquier otro dispositivo en el autobús pasará por alto esto. Tenga en cuenta que, sólo puede realizar una operación I²C a la vez! Luego, cuando hemos terminado de enviar datos al dispositivo, en “la transmisión final”. Esto le dice al dispositivo que hemos terminado, y libera el bus I²C para la siguiente operación:

    Wire.endTransmission(); // termina la transmisión

Algunos dispositivos pueden tener más de un registro y por lo tanto requieren más bytes de datos en cada transmisión. Por ejemplo, el DS1307 reloj en tiempo real tiene ocho registros para almacenar los datos de tiempo, cada uno requiere ocho bits de datos (un byte), o una RAM.

avrds1307_07Fig. 9

Sin embargo, con el DS1307 – como requiere ocho bits de datos, enviar la totalidad del lote, necesita volver a reescribir cada vez. Así que, en este caso, será necesario utilizar ocho funciones de wire.send (), cada vez. Cada dispositivo interpreta los bytes de datos enviados al mismo, por lo que se necesita la hoja de datos del dispositivo, para entender cómo usarlo.

Recepción de datos (Receiving) desde un dispositivo I²C con nuestro Arduino, requiere dos cosas: la dirección única del dispositivo (que necesitamos esté en hexadecimal) y el número de bytes de datos a aceptar desde el dispositivo. La recepción de datos en este momento, es un proceso que consta de dos etapas. Si revisamos el cuadro anterior de la hoja de datos del DS1307, tengamos en cuenta que hay ocho registros o bytes de datos allí. Lo primero que tenemos que hacer es iniciar el dispositivo I²C leyendo el primer registro, que se realiza mediante el envío de un cero al dispositivo:

    Wire.beginTransmission(device_address); // device_address, es la dirección del dispositivo
    Wire.send(0);
    Wire.endTransmission();

Entonces, el dispositivo I2C enviará los datos del primer registro cuando se le solicite. Ahora, necesitamos pedir al dispositivo los datos y la cantidad de bytes que queremos. Por ejemplo, si un dispositivo necesita tres bytes de datos, le pedimos para tres, y almacenará cada byte en su propia variable (por ejemplo, tenemos tres variables de tipo byte: a, b, y c. La primera función a ejecutar es la siguiente:

    Wire.requestFrom(device_address, 3);

Que le dice al dispositivo, “envia tres bytes de datos de vuelta” al Arduino. A continuación, inmediatamente después de esto con:

    *a = Wire.receive();
    *b = Wire.receive();
    *c = Wire.receive();

No es necesario utilizar Wire.endTransmission () al leer los datos. Ahora que, los datos solicitados se encuentran en sus respectivas variables, se pueden tratar como cualquier otra variable de bytes ordinaria.

Para una explicación más detallada del bus I2C, lea el documento explicativo u hojas de datos. Ahora vamos a utilizar nuestro conocimiento I2C mediante el control de una amplia gama de dispositivos …

COMPROBANDO EL I2C.

Cuando se inicia un proyecto en el que decidimos utilizar dispositivos I2C, es conveniente asegurarse que los dispositivos implicados se “ven”, es decir, que los dispositivos tienen una comunicación entre sí fluida. Los primeros pasos que debemos emprender cuando realicemos un proyecto que utilice el I2C, usando una punta lógica, son:

    1.- Comprobar que las líneas SCL y SDA, tienen un valor ALTO, o sea, una tensión cercana a la alimentación (5V).
    2.- Comprobar que ambas líneas SCL y SDA estando inactivas, tienen un estado ALTO.
    3.- Direccionar el master como se indica arriba, para que se comunique con un esclavo, verificando que éste responde.

Por supuesto que, si disponemos de un analizador lógico, nos facilitará la labor de análisis. La respuesta nos indicará el estado, en el que se encuentra dicha comunicación, pudiendo rectificar, hasta lograr su correcto funcionamiento.

Esto es todo, por parte de este sencillo tutorial que pretende dar mi punto de vista sobre el I2C bus.

INTRODUCCIÓN AL I2C.
Tagged on:     

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *