Saltar al contenido

Almacenamiento en memoria externa EEPROM

En esta entrada aprenderas a programar una Memoria EEPROM para cualquier PIC, puede ser el pic18F4550, PIC 16F877A, etc. No importa cual PIC uses, aquí entenderás como poder almacenar datos usando una eeprom, al final del post te dejo un código de ejemplo hecho en un PIC 16F887 para que lo bajes y lo pruebes en tu pic, solo cambiando el encabezado.

Antes que nada puedes visitar EL CURSO GRATIS DE MICROCONTROLADORES PIC

Y las LISTAS DE REPRODUCCIÓN DE YOUTUBE

Memoria EEPROM Externa con PIC

Como se tiene limitaciones para almacenar información en la memoria eeprom interna, hay memorias eeprom seriales externas con diferente capacidad que permiten almacenar mayor información. En el compilador hay drivers que permiten manejar diferentes memorias eeprom externas seriales entre ellos se tiene la memoria 24LC04B.

La conexión de la memoria eeprom externa es la siguiente:

Memoria eeprom externa pic

Preparé el siguiente video donde te explico el código implementado para utilizar el almacenamiento de memoria externa EEPROM con el PIC, con su respectiva explicación y como podemos simularlo por medio del proteus, para que posteriormente podamos llevarlo a la practica. No olvides suscribirte a mi canal de youtube dando click en el siguiente botón, para que puedas recibir toda la información que allí voy publicando.

También te podría interesar aprender como programar la EEPROM con Arduino.

Programación en CCS Compiler PIC C

Los pasos que se deben seguir para almacenar datos en memoria eeprom externa son:
1. En el encabezado del programa incluir el driver para manejar la memoria eeprom externa (en el ejemplo se trabaja con la 24LC04B)

#INCLUDE<2404.C>

2. En el programa principal inicializar la memoria

INIT_EXT_EEPROM();

3. Para escribir en la memoria se utiliza la instrucción

WRITE_EXT_EEPROM(Dirección, Valor)

Dirección: esta limitada por la capacidad de la memoria eeprom externa.
Valor: es un byte.
Esta función puede durar varios milisegundos.
Para leer el contenido de la memoria eeprom externa se utiliza la siguiente instrucción:

K=READ_EXT_EEPROM(Dirección)

Programar FLOAT en memoria EEPROM externa CCS C

Dado que una memoria eeprom solo consigue almacenar valores de 1 byte = 8 bits, debemos dividir el valor del flotante en 4 celdas de la memoria EEPROM, tal y como fue explicado y detallado en la Entrada de la Memoria EEPROM Interna del Microcontrolador PIC.

El siguiente es un ejemplo de dos funciones de cómo leer y escribir un número de punto flotante (FLOAT) desde / hacia EEPROM. El mismo concepto se puede utilizar para estructuras, matrices o cualquier otro tipo.

  • n es el desplazamiento en la EEPROM para almacenar cada valor flotante.
  • Por ejemplo: Si se almacena un flotante en la primera posición, n=0, entonces tenga en cuenta que el segundo flotante debería guardarlo en la cuarta posición, n=4 y el tercer flotante debe guardarlo en la octava posición, n=8. Esto lo debes considerar en tu lógica de programación para evitar sobre escribir datos previos.
WRITE_FLOAT_EXT_EEPROM(long int n, float data) { 
   int i;

   for (i = 0; i < 4; i++) 
      write_ext_eeprom(i + n, *((int8*)&data + i) ) ; 
}

float READ_FLOAT_EXT_EEPROM(long int n) { 
   int i; 
   float data;

   for (i = 0; i < 4; i++) 
      *((int8*)&data + i) = read_ext_eeprom(i + n);

   return(data); 
}

Ejemplo del uso de la memoria  EEPROM externa con PIC

Con un teclado telefónico, un LCD y una memoria eeprom externa digitar 4 números y luego recuperarlos, en el LCD mostrar el valor digitado y el valor recuperado.

eeprom externa 2404 con pic

Código de Implementación:

A continuación se presenta el código para que lo copies y lo pegues en tu compilador y puedas reproducirlo. Recuerda que para ver el código debes compartir o darle me gusta al contenido de este post para que más personas se beneficien de esta información.

El siguiente código está hecho en el PIC 16F887, pero si deseas usar el código en otro PIC, debes solo cambiar el encabezado, te dejo dos ejemplos de como queda el encabezado para el 18F4550 y para el 16F877A

INCLUDE<16f877A.h> //PIC16F877A

INCLUDE<18F4550.h> // PIC18F4550

/****************************************************************
*****************************************************************
******                                                  *********
******    Ejemplo del uso de la memoria interna EEPROM  *********
******                                                  *********
******    By: Sergio Andres Castaño Giraldo             *********
******    https://controlautomaticoeducacion.com/       *********
******                                                  *********
*****************************************************************
****************************************************************/

#INCLUDE <16f887.h>
#USE DELAY(CLOCK=4000000,crystal)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,NOPUT,NOLVP

//Definiciones para colocar el LCD y el teclado en el puerto B
#DEFINE USE_PORTB_LCD TRUE
#DEFINE USE_PORTB_KBD TRUE  
 
//Librerías del LCD y Teclado
#INCLUDE <LCD.C>
#INCLUDE <KBD.C> 

/*Definir SDA y SDL (PIN C4 y C3 por defecto en la librería)
Descomentar en caso de usar otros pines en el I2C*/
//#define EEPROM_SDA  PIN_C4
//#define EEPROM_SCL  PIN_C3

//Librería de la Memoria Externa
#INCLUDE <2404.C>


CHAR K;           //Defino la variable K como carácter
BYTE J=16,DIR=0;

//Programa principal
void main()
{
   // Inicializaciones
   LCD_INIT();
   KBD_INIT();
   INIT_EXT_EEPROM();
   
   //Configura las Resistencias PULL-UP del Puerto B
   port_b_pullups(0xFF); //PIC16F887
   //port_b_pullups(TRUE); //PIC16F877A

   FOR (J=12; J>=2; --J)
   {
      LCD_GOTOXY(J,1);
      LCD_PUTC("DIGITADO: ");
      DELAY_MS(100); //Retardo de 100 milisegundos
   }
   LCD_GOTOXY(12,1);    // Ubicarse en la columna 12 fila 1
   DIR=0;               // Poner la variable DIR en cero
   

   WHILE (DIR<4)                       // Mientras que DIR sea menor que 4
   {
      K=0;                             // Poner la variable K en cero
      K=KBD_GETC();
      IF( (K!='
/****************************************************************
*****************************************************************
******                                                  *********
******    Ejemplo del uso de la memoria interna EEPROM  *********
******                                                  *********
******    By: Sergio Andres Castaño Giraldo             *********
******    https://controlautomaticoeducacion.com/       *********
******                                                  *********
*****************************************************************
****************************************************************/
#INCLUDE <16f887.h>
#USE DELAY(CLOCK=4000000,crystal)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,NOPUT,NOLVP
//Definiciones para colocar el LCD y el teclado en el puerto B
#DEFINE USE_PORTB_LCD TRUE
#DEFINE USE_PORTB_KBD TRUE  
//Librerías del LCD y Teclado
#INCLUDE <LCD.C>
#INCLUDE <KBD.C> 
/*Definir SDA y SDL (PIN C4 y C3 por defecto en la librería)
Descomentar en caso de usar otros pines en el I2C*/
//#define EEPROM_SDA  PIN_C4
//#define EEPROM_SCL  PIN_C3
//Librería de la Memoria Externa
#INCLUDE <2404.C>
CHAR K;           //Defino la variable K como carácter
BYTE J=16,DIR=0;
//Programa principal
void main()
{
// Inicializaciones
LCD_INIT();
KBD_INIT();
INIT_EXT_EEPROM();
//Configura las Resistencias PULL-UP del Puerto B
port_b_pullups(0xFF); //PIC16F887
//port_b_pullups(TRUE); //PIC16F877A
FOR (J=12; J>=2; --J)
{
LCD_GOTOXY(J,1);
LCD_PUTC("DIGITADO: ");
DELAY_MS(100); //Retardo de 100 milisegundos
}
LCD_GOTOXY(12,1);    // Ubicarse en la columna 12 fila 1
DIR=0;               // Poner la variable DIR en cero
WHILE (DIR<4)                       // Mientras que DIR sea menor que 4
{
K=0;                             // Poner la variable K en cero
K=KBD_GETC();
IF( (K!='\0'))
{
LCD_PUTC(K);
WRITE_EXT_EEPROM(DIR,K);
DIR++;                     //Incrementa la variable DIR
}
}
DELAY_MS(500);                   //Retardo de 500 milisegundos
FOR (J=12; J>=2; --J)
{
LCD_GOTOXY(J,2); //Ubicarse en la fila 2 y la columna varía
LCD_PUTC("RECUPERADO: ");
DELAY_MS(100); // Retardo de 100 milisegundos
}
LCD_GOTOXY(13,2); // Ubicarse en la columna 13 fila 2
DIR=0; // Poner la variable DIR en cero
WHILE (DIR<4) // Mientras que DIR sea menor a 4
{
K=READ_EXT_EEPROM(DIR);
LCD_PUTC(K);
DIR++; //Incrementa la variable DIR
}
}
')) { LCD_PUTC(K); WRITE_EXT_EEPROM(DIR,K); DIR++; //Incrementa la variable DIR } } DELAY_MS(500); //Retardo de 500 milisegundos FOR (J=12; J>=2; --J) { LCD_GOTOXY(J,2); //Ubicarse en la fila 2 y la columna varía LCD_PUTC("RECUPERADO: "); DELAY_MS(100); // Retardo de 100 milisegundos } LCD_GOTOXY(13,2); // Ubicarse en la columna 13 fila 2 DIR=0; // Poner la variable DIR en cero WHILE (DIR<4) // Mientras que DIR sea menor a 4 { K=READ_EXT_EEPROM(DIR); LCD_PUTC(K); DIR++; //Incrementa la variable DIR } }

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.

Entradas relacionadas

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Comentarios (8)

Hola, Sergio, tengo una duda, sabes como cargar valores directamente a la eeprom? ando buscando como realizar eso para un proyecto, es decir que la eeprom no arranque en blanco

Responder

Debes tener un programador de memorias. O también puede cargar los valores inicialmente con el PIC y una vez cargados montas la eeprom en tu proyecto.

Responder

Pero para el caso del proteus que tiene la opcion de cargar un archivo para la eeprom. Sabes como se realizaria?

Responder

HOLA SERGIIO BUENAS TARDES DESDE ESPAÑA ENORABUENA POR TU CANAL ESTOY APRENDIENDO BASTATNTE TE ESCRIBO PORQUE TENGO UN PROBLEMILLA CON ESTE TEMA DE LA MEMORIA EEPROM EXTERNA Y ES QUE EL PROGRAMA CUANDO LO EJECUTO EN PROTEUS EMPIEZA BIEN ME PONE EN DISPLAY DIGITANDO PERO CUANDO DIGITO EL PRIMER CARACTER SE MUESTRA PERO LOS SUIGUIENTES NO Y EL BUS I2C ESTA COMO MULTIPLEXANDO EN VEZ DE ESTAR EN ESTADO UNO COMO VEO EN EL VIDEO EL CODIGO ES EL MISMO LE HE DADO MUCHAS VUELTAS Y NO VEO EL PROBLEMA SIN EMBARGO CUANDO COMENTO LA LINEA » WRITE_EXT_EEPROM(DIR,K); ME FUNCIONA BIEN EL TECLADO ES COMO SI NO PUDIERA TRABAJAR CON LA MEMORIA EEPROM .PERDONA POR MI IGNORANCIA Y ESPERO TU RESPUESTA GRACIAS UN SALUDO

Responder

Hola Fran, te recomiendo siempre bajes el código directamente desde el sitio web, bien sea copiando el código o bajandolo directamente en el link. Los códigos del sitio web son más actualizados que el mostrado en los videos, los cuales se van mejorando con el pasar del tiempo para solucionar todos esos tipos de inconvenientes que los usuarios reportan. Verifiqué el código que está en el botón de descarga y está funcionando correctamente, dale un vistazo. Saludos

Responder

buanas otra vez sergio el codigo lo he copiado del sitio web, siempre lo hago es el mismo ,no se si sera por proteus he leido por ahi que para estas memorias tipo 24lc…. en proteus se deben utilizar unas resistencias especiales pullups y no las genericas analogicas si no el bus no va bien .probare con eso y te cuento gracias sergio

Responder

HOLA SERGIO ,YA LO SOLUCIONE . AL FINAL ERA LO QUE TE COMENTE DE LAS RESISTENCIAS PULL UPS DE PROTEUS «PULLUP DSIMMDLS DIGITAL PRIMITIVE MODEL OF A PULL UP-RESISTOR» ESTAS RESISTENCIAS ESTAN EN EL MENU COMPONENTES ,PERO TAMBIEN SIRVEN LAS GENERICAS CAMBIANDOLAS DE ANOLOGICAS A DIGITALES .MUCHAS GRACIAS Y PERDONA MI IGNORANCIA UN ABRAZO

Responder

Excelente Fran, me alegra hayas podido solucionar el inconveniente. Saludos y muchos éxitos en tu estudio del microcontrolador PIC.

Responder