Cómo conectar una memoria Eeprom 24LC256 por el protocolo I2C a un microcontrolador

Publicado: 20/09/2014 en Programación
Etiquetas:, , , , , , , ,

Aveces cuando estamos desarrollando un prototipo nos encontramos con que el microcontrolador ya no tiene más espacio para almacenar datos, en ese momento nos damos cuenta que la única solución es emplear algún tipo de almacenamiento externo para poder seguir con el desarrollo.
Ahora la siguiente pregunta que se nos pasa por la cabeza es, ¿que tipo de almacenamiento emplear?, tenemos muchos tipos de almacenamientos pero el que vamos a utilizar o a explicar a continuación es una memoria eeprom que utiliza el protocolo I2C para la comunicación con el micro.
Trabajaremos con una memoria con matrícula 24LC256, este dispositivo es muy común y no tendréis problemas para encontrarlo, no profundizaré en explicar exhaustivamente las características, ya que toda esa información la pueden encontrar en la documentación del fabricante.

Este dispositivo se puede encontrar en varios encapsulados diferentes. El funcionamiento es igual en todos ellos, no varía para nada

Cómo pueden ver en la imagen, el chip posee ocho patillas, las patillas de la 1 a la 3, ósea A1, A2 y A3 son para el direccionamiento en el bus, cambiando los estados de estas patillas podremos manejar hasta 8 memorias en el mismo bus de datos, 23 = 8 direcciones diferentes.
La patilla 4, Vss y 8, Vcc creo que son obvias y no hará falta explicarlas ¿no?
La patilla 5, SDA es la de datos y según el fabricante es la única línea que necesita resistencias de pull-ups para que trabaje, el fabricante recomienda diferentes resistencias para diferentes velocidades de bus así como para una velocidad de 100KHz una resistencia de 10KΩ o una velocidad de 400KHz a 1MHz una resistencia de 2KΩ, ahora cada uno debería de hacer pruebas y ver cual es la mejor que les va, yo particularmente los mejores resultados que he tenido son con resistencias de 10K en las líneas SDA y SCL.
La patilla 6, SCL es la línea del reloj o clock en inglés, el máster al entablar comunicación con los dispositivos conectados al bus, llámense esclavos, envía un tren de pulsos para sincronizar la comunicación.
La patilla 7, WP (Write-Protec) es una patilla de protección, con esta patilla colocada a masa (0), podremos escribir y leer sin problemas, pero si la patilla está a positivo (1) solo podremos leer los valores almacenados desde la posición 0x0000 a 0x7FFF pero no podremos escribir en esas posiciones.

Se puede utilizar dos tipos diferentes de escritura y de lectura, se puede escribir tanto como leer byte a byte

o secuencialmente (páginas)

Aquí hay que tener especial atención a la hora de guardar datos en forma de página, el fabricante dice que el tamaño máximo que permite guardar en forma de página es de 64 bytes, y esto funciona de la siguiente manera, la memoria tiene un buffer interno gestionado por el propio dispositivo de máximo 64 bytes, por consiguiente la memoria interna está dividida en páginas de 64 bytes.
Cuando el máster establece una grabación en forma de página, el buffer interno de la memoria va guardando los datos hasta que la memoria recibe el bit de stop enviado por el máster, inmediatamente después la memoria vuelca el buffer almacenado en la posición que indicó el máster en su transmisión.
Hasta ahí queda todo claro, pero hay que tener especial atención con esto a la hora de guardar los datos en el dispositivo, porque resulta que si enviamos una página de más de 64 bytes, el contados de la memoria al llegar a la posición 64 se desborda reseteandose y colocándose en la posición inicial de la página donde estamos trabajando y machacándonos la información que tenemos guardada en esa sección, así como si enviamos una página de menos de 64 bytes pero la zona a guardar es cerca del final de esos 64 bytes y llegamos a desbordarla, el contador nos hará el mismo efecto y machacará la información del principio de esa página.

1. En la siguiente imagen pueden ver que sucede cuando se desborda el contador, empezamos a grabar en la posición 0x02FE se desbordó en la posición 0x02FF y saltó al principio de la página en la posición 0x2C0, si cuentan los bytes que hay desde la posición de inicio a la posición donde saltó, comprobarán que hay 64 bytes

En la siguiente imagen pueden ver como quedaría los datos guardados en una parte de una página de forma correcta, no llegados a rellenar la página completamente

Retomando la explicación de los tipos de comunicación que podemos tener con el dispositivo, explicaré las reglas que se tiene que respetar para poder comunicarte con la memoria.

Escritura de un byte.
Cuando el máster envía el bit de star, todos los dispositivos que estén en el bus se quedan a la escucha esperando a ver con quien quiere entablar conversación el máster. A continuación lo próximo que envía el máster es la dirección del dispositivo en el hardware del prototipo a controlar ósea en el bus, en esa transmisión de 8 bits, los primeros cuatro bits es un código único que ha grabado el fabricante a todas sus dispositivos y que es el mismo código para todas las memorias del mismo tipo, los siguientes tres bits son los que nosotros podemos modificar con las patillas de la A1 a la A3, con esto podremos meter más memorias del mismo tipo en el bus y que no haya conflicto entre ellas, anteriormente dijimos que hasta 8 dispositivos de este tipo en el mismo bus, el último bit es el que indica a la memoria si la comunicación es de escritura (0) o lectura (1). Una vez termine el tren de pulsos que le llega a la memoria, esta contesta con un bit de Ack (Acknowledgement [Confirmación] ) para decirle al máster que ha recibido la transmisión y que está preparada para el siguiente byte.
El siguiente dato a enviar es la posición donde queremos trabajar en el almacenamiento interno, como la capacidad de la memoria es grande, y el direccionamiento de la misma es un dato de 16 bits (un int), y el protocolo de comunicación I2C no permite enviar al mismo tiempo más de 8 bits (un char), el direccionamiento de la memoria se tiene que enviar de dos veces, el primer byte es el más significativo y el segundo es el menos significativo, cada vez que se envíe un dato, el esclavo tiene que contestarle al máster con un bit de Ack para confirmar que el dato ha sido recibido correctamente y poder pasar al siguiente.
A partir de este ultimo dato, enviaremos el byte (un char) de información a guardar, con lo cual la memoria responderá con un Ack y el máster enviará el bit de stop para dar por finalizada la comunicación.

Escritura de una página.
Para grabar una página entera o parte de ella el procedimiento es el mismo que para guardar un byte pero en vez de enviar el bit de stop al finalizar el primer byte de datos, se sigue enviando datos hasta alcanzar el máximo del buffer o podemos para a la mitad, ósea se puede enviar la cantidad de datos que queramos comprendidos ente 1 y 64 bytes. ¡¡¡Ojo!!!, siempre que se envíe un dato el esclavo contesta con un Ack y el máster o termina la la comunicación con un bit de stop o continua enviando datos.

Lectura de un byte.
Para leer el dispositivo se emplea la misma técnica que para la escritura, pero con la diferencia de que después del envío de la dirección de memoria a leer y el esclavo envíe el Ack, el máster enviará un reset y a continuación enviará de nuevo la dirección de la memoria en el hardware pero el último bit en vez de ser un 0 que era para escribir, envía un 1 que es para leer indicando al esclavo lo que queremos hacer, la memoria contesta con un Ack para decir que ha recibido el dato y en la siguiente instrucción ya leemos el valor del dato guardado, después de este dato el máster termina la comunicación con el bit NoAck seguido del bit de stop.

Lectura secuencial.
Con la lectura secuencial podremos leer varios bytes seguidos consecutivamente de la memoria, el principio de funcionamiento es el mismo que para la lectura de un byte, pero en lugar de que el máster termine la conexión con el bit de stop continua pidiendo datos a la memoria, creo porque de momento no lo he comprobado al cien por cien, en el modo lectura no existe la limitación de 64 bytes que hay para escribir, con lo cual se podría leer un número indeterminados de datos sin restricciones.
Una cosa que hay que tener en cuenta es que la memoria necesita un tiempo entre operación y operación, por ejemplo si hacemos una escritura en ella, tenemos que dejar un tiempo para poder o escribir o leer, si no respetamos ese tiempo el dispositivo se bloquea y no nos responderá.
En la documentación del fabricante hay una tabla donde se muestra la relación de voltaje con el tiempo de reposo del bus

A continuación voy a poner un enlace a un proyecto de comunicación entre un PIC18F2455 y una memoria 24LC256, en el proyecto implemento la comunicación por hardware como por software.
En el archivo de cabecera config.h que se encuentra en la carpeta Common, descomentando y comentado las líneas #define SW_24LC256_BYTE, #define SW_24LC256_BUFFER, etc.. podremos implementar un modo de protocolo u otro así como la escritura/lectura de un byte o de una página.
Una cosa a tener en cuenta que los puertos del protocolo i2c por hardware son diferentes que por software, así como por hardware utilizaremos los pines B0 para el SDA y B1 para el SCL y la implementación por software utilizaremos el pin B4 para el SDA y el B5 para el SCL.
En la carpeta del proyecto incluyo una carpeta donde pone Proteus, dentro de esa carpeta está el esquema en proteus que incluye una pantalla LCD donde podremos ver los datos enviados y leídos hacia y desde la memoria, no olviden cambiar los pines del bus si cambian el modo del protocolo

Espero que quede todo claro y que no haya cometido muchos errores, si alguien ve algo que no esté bien ruego lo comunique para corregir el documento.

comentarios
  1. leonardo dice:

    Excelente’ investigacion ,realmente me ubiera gustado saber si en el modo lectura no desborda los 64 byte y lee otra pagina

    • En principio no hay limitaciones para la lectura, según la documentación del fabricante y las pruebas que hice podrías leer los datos independientemente de la posición en donde estén almacenados, no obstante tu mimo puedes hacer las pruebas.
      Al final del artículo tienes un enlace a MEGA donde hay un proyecto creado con C18 y mplab IDE, a su vez incluyo una simulación en proteus donde puedes investigar.
      Si tienes alguna duda puedes consultarme e intentaré resolverlas en función de mis conocimientos

Deja un comentario