lunes, 8 de abril de 2013

Ejercicios PIC 5: i2c eeprom

En este ejercicio escribiremos en una memoria eeprom modelo 24LC256 nuestro propio nombre mediante el bus i2c por medio de un PIC 18f4550.





La memoria 24LC256 que vamos a usar en este ejercicio tiene una capacidad de 256 Kbits o lo que es lo mismo de 32 KBytes y utiliza el bus i2c para ser escrita y/o leída.

Para realizar la comunicación correctamente tendremos que fijarnos en el PDF de la memoria 24LC256.




Así vemos que lo primero que necesitaremos será un bit de start, que lo manda el maestro (el PIC 18f4550), esta condición de inicio en nuestro programa irá de la siguiente manera:

i2c_start();

---------------------------

Lo siguiente que vemos es la dirección del esclavo (memoria 24LC256) que se forma de 7 bits divididos en el código de control formado por 4 bits, y en los 3 bits de selección del chip.

El Control Code siempre será el mismo para todos los chips 24LC256 = '1010'

Nos quedan 3 bits para seleccionar cuál de todos (si es que tenemos varios) los chips 24LC256 vamos a escribir/leer. Para ello tendremos primero que conectar físicamente las patillas A0 A1 A2 a masa o a tensión según queramos y después escribir los 3 bits en nuestro programa.

EJEMPLO:


Aquí hemos conectado los 3 pines a masa por lo que en nuestro programa quedaría '000'. Si por ejemplo conectamos A0 a tensión nos quedaría '001'.

De esta manera como tenemos 3 bits podemos decir que vamos a poder usar un máximo de 8 chips 24LC256 a la vez, y si sumamos sus capacidades nos da un total de 2 Mbits o lo que es lo mismo 256 KBytes.

Por último tenemos el bit R/W:
1 para leer.
0 para escribir.

Todo esto que acabamos de ver lo aglutinamos en una sola instrucción que nos mandará todo el byte:

i2c_write(0b10100000);

Repasemos:
'1010' 4 bits de control.
'000' Seleccionamos el chip con los tres pines A0 A1 A2 a masa.
'0' Le decimos que le vamos a escribir.

---------------------------

Por último queda el bit ACK. Acknowledge literalmente significa "reconocer". Es un bit que manda el esclavo al maestro para decirle que todo está bien, que le ha llegado todo correctamente. Este bit lo manda el esclavo automáticamente y nosotros no tendremos que hacer nada.

---------------------------

Bien ya le hemos dicho a nuestro chip que le vamos a escribir pero ¿Cómo lo hacemos? Una vez más el PDF tiene la solución a nuestras preguntas. Lo primero que nos dice es que tenemos 2 maneras de escribir en nuestra memoria:

Byte Write: únicamente escribiremos un byte cada vez.
Page Write: escribiremos toda una página de memoria formada por 64 bytes de una sola vez.

Puesto que nosotros queremos controlar el número de bytes que vamos a escribir escogeremos el modo byte a byte puesto que si eligiéramos el modo página no podríamos controlar esto. Una vez decidido el modo de escritura nos queda aprender como hacerlo y para eso una vez más, fijémonos en el PDF:





En la imagen vemos que lo siguiente que tenemos que hacer es decirle que byte de la memoria le vamos a escribir. Para hacer esto tendremos que enviarle 2 bytes puesto que con 1 solo byte únicamente podríamos escribirle los primeros 256 bytes (2^8) y recordemos que esta memoria tiene 32000bytes por lo que sería un desperdicio.



Una cosa que llama la atención es ese X=don't care bit. ¿Porque no importa ese bit en concreto?
Ese bit en concreto no importa porque con 15 bits ya tenemos cubiertos los 32000bytes que tiene la memoria ya que 2^15=  32768. El bit 16 nos daría las direcciones desde la 32769 hasta la 65536 pero esas direcciones no importan porque no existen.


Para decirle a la memoria 24LC256 que dirección queremos escribir lo hacemos con las siguientes instrucciones:

i2c_write(0b00000000);  // primer byte de dirección (High)
i2c_write(variable);   //segundo byte dirección (Low)

En el segundo byte ponemos una variable (que la iniciaremos en 0b00000000 ya que queremos que empiece a escribir desde el primer byte) para que podamos ir incrementando de uno en uno la dirección en la que escribimos cada carácter de nuestro nombre.

---------------------------

Lo siguiente ya por fin, es escribir el primer carácter de nuestro nombre. Para empezar tendremos que escoger el tipo de variable que vamos a utilizar. Utilizaremos una variable tipo char para crear un string con nuestro nombre. Yo he escogido 20 caracteres de máximo pero se puede escoger cualquier otro que nos interese.

char nombre[20];

Haciéndolo de esta manera después en nuestro algoritmo podremos guardar cada carácter en una posición especifica del string así como grabar en la eeprom cualquiera de esas posiciones mediante una variable numérica que iremos incrementando.

---------------------------

Por último ya solo queda mandar la condición de STOP para que cese la comunicación, esto lo hace el maestro con la siguiente instrucción

i2c_stop();

No olvidemos que entre cada byte que se manda desde el maestro el esclavo nos responde con un bit ACK que nos indica que la comunicación funciona correctamente.

---------------------------

Ahora vamos a ver como tienen que estar las líneas SCL y SDA para hacer las condiciones de inicio de stop y los bits ACK



Condición de START: SCL en alto y SDA cambia de alto a bajo.
Condición de STOP: SCL en alto y SDA cambia de bajo a alto.
ACK: Durante el pulso acknowledges la línea SDA se pone en bajo.

RESUMIENDO

Si juntamos todo lo que hemos visto hasta ahora, para escribir el primer bit de nuestro nombre nos quedaría algo así:

char nombre[20];
int direccion=0b00000000;
int caracter;

    i2c_start(); // condición de inicio
    i2c_write(0b10100000);  // byte de control
    i2c_write(0b00000000);  // byte de direccion high
    i2c_write(incremento_memoria);   //byte direccion low
    i2c_write(nombre[caracter]); // byte de la primera letra de nuestro nombre
    i2c_stop(); //condición de paro

Con esto escribiríamos el primer carácter de nuestro nombre, ahora nos faltaría un algoritmo que nos guarde los diferentes caracteres en las diferentes posiciones del string y que una vez pulsemos intro nos grabe todos esos caracteres en la memoria eeprom externa.

Ahora pasemos a ver como funciona la simulación en proteus.


No nos olvidemos de poner las dos resistencias pull-up que necesitan las líneas SCK y SDA porque si no no funcionaría. En esta pantalla he escrito mi nombre y una vez pulsado enter me pide una confirmación, al volver a pulsar enter empezaron a salir con el debugger todos esos números y letras. Ahora vamos a explicar su significado que está estrechamente ligado a lo explicado hasta ahora. Hagamos zoom:


 Empecemos por lo sencillo, sin desplegar nada. Lo primero que vemos es una imagen como la de arriba. Cada una de las líneas desplegables nos muestra todo lo que sucede desde una condición de START hasta una condición de STOP. Lo que nos está mostrando es todo lo que ocurre al escribir cada uno de los caracteres de nuestro nombre.

El número situado más a la izquierda indica el tiempo que llevaba el programa corriendo hasta el momento en el que le llega la condición de START y el siguiente número es el tiempo que llevaba el programa corriento en el momento que le llega la condición de STOP.

Las letras siguientes es todo lo que pasa en ese tiempo, al lío:


S: Condición de START mandado por el maestro.
A0: Byte de control en hexadecimal.
A: Bit ACK mandado por el esclavo.
00: Primer byte de dirección High.
A: Bit ACK mandado por el eslcavo.
00: Segundo byte de dirección LOW.
A: Bit de ACK mandado por el exclavo.
53: Letra "S" mayúscula en hexadecimal (ver código ASCII)
A: Bit ACK mandado por el esclavo.
P: Condición de STOP mandado por el maestro



Como podemos ver en esta imagen si desplegamos el byte A0 para poder ver cada bit que lo compone vemos que estos bits son '10100000' que coincide con lo explicado en los puntos anteriores.


Si nos fijamos en la quinta columna empezando desde la derecha vemos que los números que aparecen son 00 01 02 03 04 y 05 que son las 5 primeras posiciones de memoria en la que se han escrito los 5 caracteres que tiene mi nombre.

Y si nos fijamos en la tercera columna veremos los números 53 65 72 67 69 y 6F que son los caracteres del código ASCII en hexadecimal que se corresponden con mi nombre Sergio.

Por último para comprobar que realmente hemos escrito en la memoria eeprom tenemos que pulsar el botón de pausa en Proteus, ir a la pestaña Debug y escoger la opción "I2C Internal Memory Internal U2" y ahí nos tienen que aparecer los caracteres en sus correspondientes direcciones de memoria.



Una vez analizado esto solo me queda dejaros el enlace para que podáis descargar todos los archivos tanto de mplab como de proteus.

DESCARGAR ARCHIVOS

2 comentarios: