Internal EEPROM of PIC Microcontroller (PIC18F452)

Internal EEPROM of PIC18F452 Microcontroller: Data EEPROM is used to store data permanently and it even retains data even after powering off a device or microcontroller. Almost all pic microcontrollers provide internal EEPROM to store critical data. In this tutorial, we will learn how to use internal EEPROM of Pic microcontrollers. We will also see example codes in MPLAB XC8 Compiler and MikroC Pro for PIC.

PIC Microcontroller Memory Types

There are three types of memories in a PIC Microcontroller namely, Flash Program Memory, Data Memory (RAM) and EEPROM Data Memory.

Flash Memory

Programs are written in the Flash Program Memory of a microcontroller. Because of this we can program a microcontroller and can change it many times after updating a new program. It has a fast response time.

Data Memory (RAM)

It is used for storing data temporarily during program execution. It is volatile memory and is cleared when the power is off or when CPU resets. RAM Data memory locations are also called General Purpose Registers (GPR). It also has a fast response time.

Internal EEPROM Data Memory

EEPROM stands for Electrically Erasable Programmable Read-Only Memory. EEPROM can be electrically read and write. It can be accessed through a program. It is non-volatile memory but has a slower response time or speed. The data will remain present in the memory until it is electrically erased or reprogrammed.

Now in this article, we will explain how to use internal EEPROM of PIC18F452. Internal EEPROM memory can be used to store data such as sensor data or device parameters and this data should not be lost during power off or when CPU resets. EEPROM is built inside PIC18F452 microcontroller. But internal memory is usually low in size and limited. For instance, PIC18F452 has only 256 bytes of internal EEPROM.

To avoid limitations of limited internal EEPROM, we can interface external EEPROM with Pic microcontroller also. these chips are also available to interface externally with the microcontroller. You can read this article:

Internal EEPROM PIC18452 Microcontroller

As mentioned earlier, PIC18F452 supports 256  bytes of internal data EEPROM. A programmer can both read and write data to this memory. This read/write operation can take place during the normal operation of pic microcontroller. Unlike, Pic microcontroller memory banks, this data memory is directly accessed through special function register assigned to internal EEPROM of pic18f452 microcontroller

PIC18F452 Microcontroller Internal EEPROM Registers

The internal EEPROM data memory in PIC microcontroller is not directly mapped in the register file space.It is indirectly addressed through the Special Function Registers (SFR). There are four SFRs used to read and write this memory. These registers are:

  • EECON1
  • EECON2
  • EEDATA
  • EEADR

EEPROM EECON1 Register

The important control related with the internal EEPROM is the EECON1 register which is given below. EECON1 is the control register whose five lower order bits are physically implemented. Others are physically unimplemented and used to initiate the read/write.

bit7bit6bit5bit4bit3bit2bit1bit0
EEPGDCFGSEEIFWRERRWRENWRRD
  • Bit7 EEPGD:  Flash Program or Data EEPROM Memory Select bit
EECON1bits.EEPGD = 1;  // Access Flash program memory
EECON1bits.EEPGD = 0; // Access EEPROM data memory , we select this options for data EEPROM
  • Bit6 CFGS: Flash Program/Data EEPROM or Configuration Select bit
EECON1bits.CFGS = 1;  // Access Configuration registers
EECON1bits.CFGS = 0;  //Access data EEPROM memory
  • Bit5 EEIF: It shows write operation completed ( Flag  interrupt )
EECON1bits.EEIF = 1; // Write operation completed (must be cleared in software)
EECON1bits.EEIF = 0; //Write operation is not completed or not started
  • WRERR:   EEPROM Error Flag bit
EECON1bits.WRERR = 1; // Write operation is terminated (by any reset e.g MCLR reset or any WDT reset)
EECON1bits.WRERR = 0;  // Write operation completed
  • WREN: EEPROM Write Enable bit
EECON1bits.WREN = 1;  //Allows write into EEPROM
EECON1bits.WREN = 0; // Inhibits write to the data EEPROM
  • WR: Write Control bit
EECON1bits.WR = 1; // Initiates an EEPROM write cycle
EECON1bits.WR = 0; // Write cycle to the data EEPROM is complete
  • RD:  Read Control bit
EECON1bits.RD = 1; // Initiates an EEPROM read
EECON1bits.RD = 0; // Read cycle to EEPROM is complete

When WREN bit is set, it will allow a write operation. Control bits RD and WR initiate read and write respectively. These bits cannot be cleared and only set in the software. They are cleared in hardware at completion of the read or write operation. This inability to clear the bit in software prevents the accidental or premature termination of a write operation.

On power-up, the WREN bit is clear. The WRERR bit is set when a write operation is interrupted by an MCLR, Reset or a Watchdog time-out Reset during normal operation. When this situation occurs, we can check the WRERR bit and rewrite the location. Interrupt flag bit EEIF is set when a write is complete. It must be cleared in software.

Internal EEPROM EECON2 Register

EECON2 is not a physical register. For Reading, EECON2 register will read all bits as ‘0’. The EECON2 register is used exclusively in the Data EEPROM write sequence.

EEDATA Register

EEDATA Register holds the 8-bit data for read/write operation. EEPROM data memory allows only a single byte to be read and write. When a byte is writing, it automatically erases the location and writes the new data. The EEPROM data memory is rated for high erase/write cycles. The write time is controlled by an on-chip timer.

EEADR Register

EEADR register holds the address of the EEPROM location which is to be accessible. It can access up to 256 locations of Data EEPROM in PIC18F452. The address range always starts at 00h and goes all over the memory available.

EEPROM SIZEAddress Range
64(00-3F)h
128(00-7F)h
256(00-FF)h

PIC Microcontroller EEPROM Code MPLAB XC8 Compiler

In this section, we will see how to configure these register in MPLAB XC8 compiler. How to write and read data from internal EEPROM.

Reading Data from PIC18452 Internal EEPROM

  1. The address of the memory location to be read is given to EEADRregister.
  2. Select EEPROM data memory by clearing the EEPGD control bit of EECON1 Register.
  3. Set the RD bit of EECON1 Register to initiate the read cycle.
  4. Then we can read data through EEDATA register.
unsigned char readEEPROM(unsigned char address)
{
EEADR = address; //Address to be read
EECON1bits.EEPGD = 0;//Selecting EEPROM Data Memory
EECON1bits.RD = 1;//Initialise read cycle
return EEDATA; //Returning data
}

It reads data from a specified address. The parameter address is microcontroller dependent. For PIC16 family it is of short type, and for PIC18 family it is of integer type. Here this function’s parameter (int) supports microcontrollers with more than 256 bytes of EEPROM. Give a delay of minimum 20ms between successive use of routines EEPROM_Write and EEPROM_Read. Otherwise, a microcontroller may return an undefined result.

Writing Data to PIC18452 Internal EEPROM

  • The address of the memory location where data to be written is given to the EEADR register.
  • 8-bit data which is to write is written in the EEDATA register.
  • Select EEPROM data memory by clearing the EEPGD control bit of EECON1 Register.
  • Set the WREN control bit of EECON1 Register to enable write operations.
  • Store the interrupt register INTCON if interrupts are enabled in the program, and then disable them.
  • There exists a special instruction sequence using EECON2 register is executed.
  • Set the WR bit to initiate an EEPROM write cycle.
  • Enable Interrupts if using.
  • Disable the write operations by clearing WREN control bit.
  • WR control bit is cleared if write cycle to the data EEPROM is complete or EEIF interrupt flag bit is set when write operation is completed. EEIF bit must be cleared in the program.
void writeEEPROM(unsigned char address, unsigned char data)

{
unsigned char INTCON_SAVE;//To save INTCON register value
EEADR = address; //Address to write
EEDATA = data; //Data to write
EECON1.EEPGD = 0; //Selecting EEPROM Data Memory
EECON1.WREN = 1; //Enable writing of EEPROM
INTCON_SAVE=INTCON;//Backup INCON interupt register
INTCON=0; //Diables the interrupt
EECON2=0x55; //Required sequence for write to internal EEPROM
EECON2=0xAA; //Required sequence for write to internal EEPROM
EECON1.WR = 1; //Initialise write cycle
INTCON = INTCON_SAVE;//Enables Interrupt
EECON1.WREN = 0; //To disable write
while(PIR2.EEIF == 0)//Checking for complition of write operation
{
asm nop; //do nothing
}
PIR2.EEIF = 0; //Clearing EEIF bit
}

Internal EEPROM PIC Microcontroller Example

In this example, we connect LEDs with PORTC of PIC18F452 microcontroller. First, we will write data to internal EEPROM. The data will be of a type that will turn on these LEDs sequentially from D1-D7. After writing data, we will read this data from the same addresses and send this data to PORTC.

Internal EEPROM PIC Microcontroller Example MPLAB XC8 Compiler Simulation

 

In this example, we firstly write data to the EEPROM data memory and then it is read through some PORT. We write 00000001 to the first memory location, 00000010 to second, 000000100 to third and then sequentially up to 10000000. After that, it is read sequentially and output through PORTC.

Internal EEPROM Code Example MPLAB XC8

  • First, create a new project in the MPLAB XC8 compiler and select microcontroller PIC18F452
  • This code also works with other PIC18 series microcontrollers having same register configurations
  •  Generate configuration file and select external oscillator from settings
  • After that upload this code to pic microcontroller
#include <xc.h>
#include "config.h"
void delayms(unsigned int nMilliseconds)
{
#define CYCLES_PER_MS 100 /* Number of decrement-and-test cycles. */
unsigned long nCycles = nMilliseconds * CYCLES_PER_MS;
while (nCycles--);
}
unsigned char readEEPROM(unsigned char address)
{
EEADR = address; //Address to be read
EECON1bits.EEPGD = 0; //Selecting EEPROM Data Memory
EECON1bits.RD = 1; //Initialise read cycle
return EEDATA; //Returning data
}

void writeEEPROM(unsigned char address, unsigned char data)
{
unsigned char INTCON_SAVE; //To save INTCON register value
EEADR = address; //Address to write
EEDATA = data; //Data to write
EECON1bits.EEPGD = 0; //Selecting EEPROM Data Memory
EECON1bits.WREN = 1; //Enable writing of EEPROM
INTCON_SAVE=INTCON; //Backup INCON interupt register
INTCON=0; //Diables the interrupt
EECON2=0x55; //Required sequence for write to internal EEPROM
EECON2=0xAA; //Required sequence for write to internal EEPROM
EECON1bits.WR = 1; //Initialise write cycle
INTCON = INTCON_SAVE; //Enables Interrupt
EECON1bits.WREN = 0; //To disable write
while(PIR2bits.EEIF == 0); //Checking for complition of write operation
PIR2bits.EEIF = 0; //Clearing EEIF bit
}

void main(void) 
{
unsigned int i, a; //i for address, a for data
TRISC = 0; //PORT C as output port
do
{
for(i=0,a=1;i<8;i++)
{
writeEEPROM(i, a); //writing data to first memory location and then goes upto last location
delayms(20);
a = a<<1;
}

for(i=0;i<8;i++)
{
PORTC = readEEPROM(i); //reading data sequentially and output through PORT C
delayms(1000);
}
}while(1);

return;
}

Internal EEPROM with MikroC Pro for PIC

If you want to use mikroC for the pic compiler, you can use its built-in library. We don’t need to worry about internal configuration of control registers.

EEPROM LIBRARY MikroC Pro

MikroC provides some library function for comfortable work with EEPROM.

 

EEPROM_READ Function

unsigned short EEPROM_Read(unsigned int address): It Reads data from a specified address. The parameter address is microcontroller dependent. For PIC16 family it is of short type, and for PIC18 family it is of integer type. Here this function’s parameter (int) supports microcontrollers with more than 256 bytes of EEPROM. Give a delay of minimum 20ms between successive use of routines EEPROM_Write and EEPROM_Read, otherwise, a microcontroller may return an undefined result.

EEPROM_Write Function 

unsigned short EEPROM_ Write (unsigned int address): This function Writes data to the specified address. All interrupts should be disabled during the execution of the EEPROM_Write routine.

Internal EEPROM PIC Microcontroller Code MikroC Pro

internal EEPROM of pic microcontroller

This code working is the same as the last example with MPLAB XC8 compiler.

 

void main()
{
unsignedinti, a;                  //i for address, a for data
TRISC  = 0;                            //PORT C as output port
do
   {
for(i=0,a=1;i<8;i++)
      {
     Eeprom_Write(i, a);      //writing data to first memory location and then goes upto last location 
     Delay_ms(20);
       a = a<<1;
      }
for(i=0;i<8;i++)
      {
         PORTC = Eeprom_Read(i);        //reading data sequentially and output through PORT C
         Delay_ms(1000);
      }

}while(1);
}

This is a complete tutorial about how to use EEPROM of pic microcontroller. It is very easy to use and the MikroC compiler makes it very easy due to its built-in libraries. But if you prefer to use MPLAB XC8 compiler, you can use it also.

Where to use Internal EEPROM?

While working on microcontroller projects, you might need to store the state of LEDs, push buttons or some data that you want to use lately for calculations. Instead of using these things in variables, you can store them in data EEPROM, because it will save you program memory and make your code efficient to add more features in your projects.

One another application could be a digital electronic lock. In the electronic lock, we will store the password value in internal EEPROM and whenever use enters the password, we compare uses entered password with the stored password. If both passwords match, the lock will open. Otherwise, remain close. Therefore, in this tutorial, we show you how to write and retrieve data.

What to do Next?

You can try to do these exercise problems to enhance your skills of working with EEPROM:

  • How to write and read integer value from EEPROM?
  • How to read/write float value?
  • Store states of LEDs and Switches

Read and Write Integer/Float/Long/String to Internal EEPROM

In the last section, we have seen internal EEPROM of pic microcontroller (PIC18F452) is organized in byte by byte format. Therefore, we can save only one byte at one location of memory. What if we need to store other data types such as integer, float, double, long double and string? In this section, we will see codes to read and write other data types from the internal EEPROM of pic microcontroller.

Writing Integer value

In the case of PIC18 and PIC16 series, integer data is of 2 bytes. Therefore, we need to divide data into two parts to store in internal electrical erasable memory. write_integer function will write a low byte at a first location and higher byte on the next location. The lo() and hi() are built-in functions in MikroC Pro that are used to extract low and high byte from a given number.

void write_integer(char address, int number)
{
eeprom_write(address, lo(number));   // lo(number) function extracts lower bytes from a number
delay_ms(20);
eeprom_write(address+1,hi(number));
delay_ms(20);
}

Reading Integer value

int read_integer(char address)
{
int th;
lo(th)=eeprom_read(address);
hi(th)=eeprom_read(address+1);
return th;
}

Reading/Writing Float

This write_float writes a float data type.

void write_float(char address, float number){
eeprom_write(address,lo(sayi));
delay_ms(20);
eeprom_write(address+1,hi(number));
delay_ms(20);
eeprom_write(address+2,higher(number));
delay_ms(20);
eeprom_write(address+3,highest(number));
delay_ms(20);
}

This function reads a float data type from on-chip EEPROM

float read_float(char address){
float th;
lo(th)=eeprom_read(address);
hi(th)=eeprom_read(address+1);
higher(th)=eeprom_read(address+2);
highest(th)=eeprom_read(address+3);
return th;
}

Writing/Reading Long

write_long() used to store unsigned long data types in on-chip Data memory.

void write_long(char address, unsigned long value)

{
eeprom_write(address,lo(value));
delay_ms(20);
eeprom_write(address+1,hi(value));
delay_ms(20);
eeprom_write(address+2,higher(value));
delay_ms(20);
eeprom_write(address+3,highest(value));
delay_ms(20);
}

read_long() used to retrieve unsigned long data type from on-chip Data memory.

unsigned long read_long(char address)
{
unsigned long th;
lo(th)=eeprom_read(address);
hi(th)=eeprom_read(address+1);
higher(th)=eeprom_read(address+2);
highest(th)=eeprom_read(address+3);
return th;
}

 

Leave a Comment