martes, 4 de diciembre de 2012

Escritura en EEprom via I2c

En la siguiente entrada vamos a realizar la escritura de datos en una memoria EEPROM.

Ejercicio:

Mediante puerto serie Rs232 en consola de hyperterminal, nos preguntará por nuestro nombre, una vez escrito el nombre pulsaremos la tecla "intro", y nos volverá a preguntar el programa si queremos grabar los datos en la memoria. Si pulsamos la tecla correspondiente ya sea "intro" o la tecla que hayamos definido se guardarán los datos en la memoria.
Para realizar la comunicación y transferencia de datos a la EEprom lo vamos a realizar via I2C.

Analizado el enunciado del ejercicio vamos a detallar los integrados a utilizar.

PIC 18F4550

El Pic que vamos a emplear como en ejercicios anteriores es el Pic18F4550.
Como se puede observar en la siguiente fotografía, hemos asignado la linea SDA en RB0 y SCL en RB1.
El virtual Terminal de Proteus para hacer la simulación de comunicación por puerto serie, lo hemos conectado en RC6 para Rx y RC7 para Tx. Debemos recordar que si fuéramos a pasar el diseño a una pcb, tenemos que añadir el Max232 para adaptar niveles, pero en Proteus para la simulación no es necesario.
También se puede ver que hemos añadido como extra un Lcd de 2x16 para poder visualizar los datos enviados a la EEprom, conectado al puerto D de nuestro Pic.



LCD(OPCIONAL)

Aquí podemos observar el Lcd empleado con sus correspondientes conexiones al Pic 18F4550. 


PULL UP

Las lineas SDA y SCL son bidireccionales, las vamos a conectar al positivo (5Vdc) de la alimentación a través de resistencias en Pull-Up. De esta forma cuando el Bus se encuentre libre, las dos líneas se encontrarán en nivel alto.


EEPROM 25LC256 Y DEBUGGER

La memoria EEprom que vamos a utilizar corresponde al integrado 25LC256, es necesario que leamos el datasheet para conocer su esquemático de conexión hardware y además tenemos que analizarlo para poder realizar la programación correctamente.
Desde el punto de visto Hardware:
Hemos conectado las salidas A0, A1, A2 a Gnd, ya que simplemente vamos a utilizar una EEprom y no es necesario realizar comparaciones entre otros dispositivos.
El pin Wp, corresponde al pin de protección de escritura, por tanto lo conectamos a gnd, para poder escribir.
Por último los pines SCK y SDA, los conectamos a sus líneas correspondientes. 
Además hemos añadido un debugger que tiene Proteus de I2C para depuración y control.



Aquí se puede observar el resultado final del diseño en Isis para que podamos hacer la simulación.


PROGRAMACIÓN

Realizado el diseño en Proteus nos pondremos manos a la obra para realizar la programación. Así que abriremos MPLAB y crearemos un nuevo proyecto llamado "Comunicacion_I2c".
En primer lugar definiremos los dispositivos y estableceremos su configuración, en la cabecera.

#include <18f4550.h>
#FUSES  INTHS,MCLR,PUT,BROWNOUT
#use delay(INTERNAL=4MHZ)   // configuramos el reloj interno
#use rs232 (BAUD =9600 , XMIT=PIN_C6 , RCV=PIN_C7 ) // configuramos el Rs232 RC6= Tx  RC7= Rx
#use I2C(Master, sda=pin_b0, scl=pin_b1)  // habilitamos I2C y definimos SDA y SCL 
#include <lcd.c>  

A continuación definiremos las variables globales.

char dato[15];  // esta es la variable tipo char donde se almacenaran los caracteres.
char c;
int dato2=0b00000000;
int x,escribir;
int i;



Las funciones utilizadas

#INT_RDA                            //INT_RDA es una interrupción por RS232
void rda_int()
{
c = getchar(); // almacenamos caracter en variable c con getchar
putc(c);
if(c==13  || x==14){escribir=1;dato[x]=0;}  // si pulsamos intro(13 es el valor en ASCII intro) o llegamos al maximo del array que hemos definido en dato, escribir=1
else  // si no se cumple el if, se siguen almacenando caracteres
{
dato[x]=c; // almacena en string x los valores de c
x++;
}

Por último llegamos al programa principal

void main()
{
 x=0;
 lcd_init();
 enable_interrupts(INT_RDA);      //Habilita interrupción por recepción RS232
 enable_interrupts(GLOBAL);       //Habilita interrupcion global
 escribir=0;
 puts( " ¿Como te llamas?" );  // se envía una cadena vía Rs232 a hyperterminal
 while(escribir==0)
{}
puts("Pulsa enter para grabar en la EEPROM");
c = getchar();
   if(c!=13){escribir=0;}  //si c es distinto de 13 sale del programa, si pulso intro graba.
else
for (i=0;i<15;i++) // for que extrae las posiciones del string dato y graba en eeprom
{
if (dato[i]==0) break;
                       /* Aqui es donde arrancamos el I2c con la condición de inicio y establecemos la       configuración de escritura en la EEprom, tal y como se aprecia en la foto procedente del datasheet para realizar la escritura tenemos que configurar en I2c_write el byte de control, el byte de  dirección  alta, el byte de dirección baja y por último ya enviaríamos los datos


Para finalizar estableceremos el paro con i2c_stop() */

i2c_start();  // esta es la condición de inicio
i2c_write(0b10100000);  // byte de control de la memoria EEProm
i2c_write(0b00000000);  // byte de direccion
i2c_write(dato2);       //byte direccion incremento, corresponde a las             posiciones donde se almacenaran los caracteres
  i2c_write(dato[i]); //escribre el propio dato almacenado en el string
   i2c_stop(); // condicion de paro
dato2 ++;
       printf(lcd_putc,"\n\r dato: %c, %d",dato[i],i);  // printf el dato y la posicion en el Lcd
delay_ms(2);
}
}


SIMULACIÓN

Como ya hemos creado el código y nos ha compilado sin problemas en Mplab, pasemos a la simulación, asi que cargamos el archivo *.cof o *.hex en el Pic y este es el resultado.
En el momento que arrancamos el programa, nos envía por puerto serie al virtual terminal la pregunta, entonces podemos escribir en la consola, como si fuese un hyperterminal, para enviar los datos. Mientras estamos escribiendo cada caracter, salta la interrupcion Int_RDA y se están almacenando los datos en la variable dato del programa.


Cuando hemos acabado de escribir un nombre, pulsamos la tecla intro, y nos pasa a la pregunta de confirmación para realizar la escritura, como se puede observar, si hacemos un pause, la memoria de la EEprom no ha almacenado nada aún.


Una vez ejecutado y pulsado la tecla intro, nos almacena los datos en la memoria EEprom tal y como se aprecia en la captura, y además el Lcd nos ha mostrado los caracteres escritos y su posición en la memoria.



Descarga aquí el código



1 comentario:

  1. gracias amigo por compartir tus programas yo ando buscando como guardar dos datos de 8 bits cada uno que se comparan con dos datos que me emite un control remoto rf ya lo logre con un solo control lo grabo en el receptor y luego cuando activo el cpntrol rf me compara con el q guarde y funciona perfecto pero me gustaria que el me pudiera guardar varios controles algo asi como que un for me guardara en la 0 y en la 1 el primer control luiego en la 2 y en la 3 el 2do control y q despues yo compare con otro for cada dos direcciones 0y1 para el control 1 2y3 para el control 2 y asi sucesivamente

    ResponderEliminar