Memoria EEPROM Interna, Pic C Compiler

En esta sección aprenderás a programar la memoria EEPROM interna que nos permite almacenar datos en el microcontrolador, incluso cuando se apaga, los datos pueden ser de 8 bits, 16 bits, 32 bits y de tipo flotante. 

Memoria EEPROM

La EEPROM (Electrically Erasable Programmable Read-Only Memory) es un tipo de memoria no volátil que se encuentra comúnmente en los microcontroladores PIC (Programmable Interface Controllers) de Microchip Technology. La EEPROM se utiliza para almacenar datos que necesitan ser persistentes incluso cuando el microcontrolador se apaga.

La memoria EEPROM en los microcontroladores PIC está organizada en bytes individuales, y cada byte se puede leer y escribir de forma independiente. La capacidad de la EEPROM puede variar según el modelo de microcontrolador PIC específico, pero suele oscilar entre unos pocos cientos de bytes y varios kilobytes.

La EEPROM se utiliza típicamente para almacenar datos como configuraciones de usuario, valores calibrados, contraseñas y otros datos importantes. La escritura en la EEPROM implica la transferencia de datos a través del bus de datos del microcontrolador y la programación de los bits correspondientes en la memoria. La lectura de datos de la EEPROM simplemente implica la lectura de los bits almacenados en una ubicación de memoria específica.

Es importante tener en cuenta que la EEPROM tiene una vida útil limitada en términos de ciclos de escritura y borrado. Cada ubicación de memoria de la EEPROM puede soportar un número limitado de ciclos de escritura antes de que se desgaste. Por lo tanto, es recomendable utilizar técnicas como la escritura selectiva o la implementación de algoritmos de corrección de errores para maximizar la vida útil de la EEPROM.

Funciones

El microcontrolador PIC18F4550 tiene una memoria de 256 bytes de almacenamiento, es decir que tiene la capacidad de guardar 8bits en 256 direcciones de memoria. Cada dirección de memoria tiene un limite de escritura y borrado que es de 100 000 ciclos de acuerdo con la hoja de especificaciones del microcontrolador.


write_eeprom(address, int8 data); 
valor = read_eeprom(address); 

Para guardar o escribir un dato en una dirección de memoria se utiliza la función «write_eeprom()».


write_eeprom(address, int8 data);  

adress: dirección de memoria donde se guardara el dato

int8 data: dato de 8 bits que se guardara en la dirección de memoria.

Para leer un dato en una dirección de memoria se utiliza la función «read_eeprom()», y en este caso el dato se asigna a una variable declarada «int8 valor».


int8 valor;
 
valor = read_eeprom(address); 

adress: dirección de memoria donde se leerá el dato.

Ejemplo: 8 bits


int8 valor;

valor = 255;

write_eeprom(0, valor);  // Guarda el valor en la dirección de memoria “0”

valor =  read_eeprom(0);  // Lee el valor en la dirección de memoria “0” 

Existen otras funciones que permiten guardar un dato mayor a 8 bits, y se hace guardando el dato en dos o más direcciones de memoria dependiendo de la función. 


write_int16_eeprom(address, int16 data); 
valor = read_int16_eeprom(address); 

write_int32_eeprom(address, int32 data); 
valor = read_int32_eeprom(address); 

write_float_eeprom(address, float data); 
valor = read_float_eeprom(address); 

Para utilizar estas funciones es necesario descargar una librería y extraerla en la carpeta proyecto.

Ejemplo: 16 bits


int16 valor;

valor = 65535;

write_int16_eeprom(0, valor); // Guarda el valor en la dirección de memoria “0” y “1”

valor = read_int16_eeprom(0); // Lee el valor en la dirección de memoria “0” y “1” 

Ejemplo: 32 bits


int32 valor;

valor = 4294967295;

write_int32_eeprom(0, valor); // Guarda el valor en la dirección de memoria “0”, “1”, “2” y “3”

valor = read_int32_eeprom(0); // Lee el valor en la dirección de memoria “0”, “1”, “2” y “3” 

Circuito de conexión

Procedimiento

Inicialmente se definen los pines de entrada conectados a los botones.


#define mas input(pin_b0)
#define menos input(pin_b1)

Se declara una variable entera de 8 bits «valor».


int8 valor;

Se habilitan las interrupciones externas para los pines conectados a los botones.


   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);

Se hace la lectura del dato en la dirección de memoria «0» y se guarda en dato leído en la variable «valor».


valor = read_eeprom(0);    //(address)

Cuando se detecta un pulso de entrada en el pin de interrupción «INT0» correspondiente al botón «mas», se habilita la interrupción y el programa se coloca en la directiva de la interrupción «#INT_EXT». Se incrementa la variable «valor» en 1 y se guarda el valor de la variable en la dirección «0», de la memoria eeprom.


#INT_EXT
void interrupt_mas()
{
   delay_ms(1); //antirrebote

   valor+=1;
   write_eeprom(0, valor);    //(address, value)

   while(mas)
   {}
}

Cuando se detecta un pulso de entrada en el pin de interrupción «INT1» correspondiente al botón «menos», se habilita la interrupción y el programa se coloca en la directiva de la interrupción «#INT_EXT1». Se decrementa la variable «valor» en 1 y se guarda el valor de la variable en la dirección «0», de la memoria eeprom.


#INT_EXT1
void interrupt_menos()
{
   delay_ms(1); //antirrebote

   valor-=1;
   write_eeprom(0, valor);    //(address, value)

   while(menos)
   {}
}

Finalmente se muestra el valor actual en la pantalla OLED.


void mostrar()
{
   char texto[20];

   sprintf(texto,"Val:%03u ",valor);
   OLED_DrawText(1,1,texto,1);

   OLED_Display();//Muestra la información en pantalla;
}

Código completo: int8


#FUSES NOMCLR

#use i2c(Master,Fast, sda=PIN_D3, scl=PIN_D2, force_sw, stream=OLED_stream)//parametros I2C

//#define SH1106_128_64
//#define SSD1306_128_64
#define SSD1306_128_32 //DEFINE EL MODELO DE LA PANTALLA OLED

#include "OLED_I2C.c" //libreria oled I2C

#define mas input(pin_b0)
#define menos input(pin_b1)

int8 valor;

#INT_EXT
void interrupt_mas()
{
   delay_ms(1); //antirrebote

   valor++;
   write_eeprom(0, valor);   //(address, value)

   while(mas)
   {}
}

#INT_EXT1
void interrupt_menos()
{
   delay_ms(1); //antirrebote

   valor--;
   write_eeprom(0, valor);   //(address, value)

   while(menos)
   {}
}

void mostrar()
{
   char texto[20];

   sprintf(texto,"Val:%03u", valor);
   OLED_DrawText(1,1,texto,2);

   OLED_Display();//Muestra la información en pantalla;
}

void main()
{
   OLED_Begin();
   OLED_ClearDisplay();

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);

   valor = read_eeprom(0);   //(address)
   while(TRUE)
   {
      mostrar();
   }

}

Código completo: int16


#include "internal_eeprom_pic.c" 

#FUSES NOMCLR

#use i2c(Master,Fast, sda=PIN_D3, scl=PIN_D2, force_sw, stream=OLED_stream) //parametros I2C

//#define SH1106_128_64
//#define SSD1306_128_64
#define SSD1306_128_32 //DEFINE EL MODELO DE LA PANTALLA OLED

#include "OLED_I2C.c" //libreria oled I2C

#define mas input(pin_b0)
#define menos input(pin_b1)

int16 valor; 

#INT_EXT
void interrupt_mas()
{
   delay_ms(1); //antirrebote
   
   valor++;
   write_int16_eeprom(0, valor);   //(address, value)
   
   while(mas)
   {}
}

#INT_EXT1
void interrupt_menos()
{
   delay_ms(1); //antirrebote
   
   valor--;
   write_int16_eeprom(0, valor);   //(address, value)
   
   while(menos)
   {} 
}

void mostrar()
{
   char texto[20];
   
   sprintf(texto,"Val:%05lu", valor);
   OLED_DrawText(1,1,texto,2);

   OLED_Display();//Muestra la información en pantalla;
}

void main()
{
   OLED_Begin();
   OLED_ClearDisplay();

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);
     
   valor = read_int16_eeprom(0);   //(address) 
   while(TRUE)
   {
      mostrar(); 
   }

}

Código completo: int32


#include "internal_eeprom_pic.c" 

#FUSES NOMCLR

#use i2c(Master,Fast, sda=PIN_D3, scl=PIN_D2, force_sw, stream=OLED_stream) //parametros I2C

//#define SH1106_128_64
//#define SSD1306_128_64
#define SSD1306_128_32 //DEFINE EL MODELO DE LA PANTALLA OLED

#include "OLED_I2C.c" //libreria oled I2C

#define mas input(pin_b0)
#define menos input(pin_b1)

int32 valor; 

#INT_EXT
void interrupt_mas()
{
   delay_ms(1); //antirrebote
   
   valor++;
   write_int32_eeprom(0, valor);   //(address, value)
   
   while(mas)
   {}
}

#INT_EXT1
void interrupt_menos()
{
   delay_ms(1); //antirrebote
   
   valor--;
   write_int32_eeprom(0, valor);   //(address, value)
   
   while(menos)
   {} 
}

void mostrar()
{
   char texto[20];
   
   sprintf(texto,"Val:%010lu", valor);
   OLED_DrawText(1,1,texto,2);

   OLED_Display();//Muestra la información en pantalla;
}

void main()
{
   OLED_Begin();
   OLED_ClearDisplay();

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);
     
   valor = read_int32_eeprom(0);   //(address) 
   while(TRUE)
   {
      mostrar(); 
   }

}

Código completo: float


#include "internal_eeprom_pic.c"

#FUSES NOMCLR

#use i2c(Master,Fast, sda=PIN_D3, scl=PIN_D2, force_sw, stream=OLED_stream)//parametros I2C

//#define SH1106_128_64
//#define SSD1306_128_64
#define SSD1306_128_32 //DEFINE EL MODELO DE LA PANTALLA OLED

#include "OLED_I2C.c" //libreria oled I2C

#define mas input(pin_b0)
#define menos input(pin_b1)

float valor;

#INT_EXT
void interrupt_mas()
{
   delay_ms(1); //antirrebote

   valor+=0.1;
   write_float_eeprom(0, valor);   //(address, value)

   while(mas)
   {}
}

#INT_EXT1
void interrupt_menos()
{
   delay_ms(1); //antirrebote

   valor-=0.1;
   write_float_eeprom(0, valor);   //(address, value)

   while(menos)
   {}
}

void mostrar()
{
   char texto[20];

   sprintf(texto,"Val:%0.2f ", valor);
   OLED_DrawText(1,1,texto,2);

   OLED_Display();//Muestra la información en pantalla;
}

void main()
{
   OLED_Begin();
   OLED_ClearDisplay();

   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);

   valor = read_float_eeprom(0);   //(address)
   while(TRUE)
   {
      mostrar();
   }

}
Scroll al inicio