
Internal EEPROM Read Write program for PIC18F4550
EEPROM of PIC18F (PIC18F4550 Microcontroller)
- Complete Video Course on PIC18F4550 Microcontroller
- Introduction: Internal EEPROM of the PIC18F4550
- Prerequisites
- EEPROM Overview
- EEPROM Memory Registers
- EEPROM Write Procedure
- EEPROM Read Procedure
- Example Application
- Important Considerations
- Working Principle
- Output Observation
- Applications
- Summary
- Learn More
- Complete Video Course on PIC18F4550 Microcontroller
- 💬Frequently Asked Questions (FAQ)
Would you like to join our comprehensive practical video course on the PIC18F4550 Microcontroller?
Complete Video Course on PIC18F4550 Microcontroller

Introduction: Internal EEPROM of the PIC18F4550
The PIC18F4550 microcontroller features an internal Electrically Erasable Programmable Read-Only Memory (EEPROM) that provides non-volatile data storage. This means the data remains even after the power is turned off.
The EEPROM is ideal for saving configuration settings, calibration data, and other user parameters that must persist across resets. Understanding how to read and write EEPROM data is essential for developing reliable and intelligent embedded systems.
Prerequisites
Before starting this topic, readers should have:
- Basic knowledge of PIC18F4550 architecture and memory organization.
- Experience with MPLAB X IDE and XC8 compiler.
- Understanding of GPIO programming and C programming basics.
- Optionally reviewed the blog on Timers (used for simple delays) and CCP Module (for timing assistance).
EEPROM Overview
The PIC18F4550 provides 256 bytes of internal data EEPROM that can be individually read or written. Unlike Flash memory, EEPROM allows byte-level access without erasing the entire block.
Key characteristics include:
- 256 × 8-bit storage capacity.
- Separate address space from program memory.
- Byte-by-byte read and write capability.
- Data retention for over 40 years and write endurance of 1,000,000 cycles.
EEPROM Memory Registers
The EEPROM operation relies on a few key registers:
- EEADR – Holds the address of the byte to be accessed.
- EEDATA – Holds the data byte to be written or read.
- EECON1 – Controls the EEPROM read/write operation.
- EECON2 – A special register used for write unlock sequence (not physically implemented).
EEPROM Write Procedure
Writing to EEPROM involves a protected sequence to prevent accidental writes.
Steps to Write a Byte
- Load the target address into EEADR.
- Load the data byte into EEDATA.
- Clear the EEPGD bit to select data EEPROM.
- Clear CFGS to select EEPROM memory.
- Set WREN = 1 to enable writing.
- Disable interrupts to protect the sequence.
- Write 0x55 then 0xAA to EECON2 (unlock sequence).
- Set WR = 1 to start the write operation.
- Wait for WR = 0 (write complete).
- Clear WREN to disable further writes.
Example Code (EEPROM Write)
#include <xc.h>
void EEPROM_Write(unsigned char address, unsigned char data)
{
while (WR); // Wait for previous write
EEADR = address; // Set address
EEDATA = data; // Load data
EECON1bits.EEPGD = 0; // Select data EEPROM
EECON1bits.CFGS = 0; // Access EEPROM memory
EECON1bits.WREN = 1; // Enable write
INTCONbits.GIE = 0; // Disable interrupts
EECON2 = 0x55; // Required unlock sequence
EECON2 = 0xAA;
EECON1bits.WR = 1; // Start write
while (EECON1bits.WR); // Wait until done
EECON1bits.WREN = 0; // Disable write
INTCONbits.GIE = 1; // Re-enable interrupts
}CEEPROM Read Procedure
Reading from EEPROM is simpler and does not require unlock sequences.
Steps to Read a Byte
- Load the address into EEADR.
- Clear EEPGD to select EEPROM.
- Clear CFGS.
- Set RD = 1 to initiate the read.
- Read the data from EEDATA.
Example Code (EEPROM Read)
unsigned char EEPROM_Read(unsigned char address)
{
EEADR = address; // Set address
EECON1bits.EEPGD = 0; // Select EEPROM
EECON1bits.CFGS = 0;
EECON1bits.RD = 1; // Start read
return EEDATA; // Return data
}
CExample Application
A common use case is storing the brightness level of an LED or calibration values that should persist after a reset.
Example: Save and Retrieve LED Brightness
#define BRIGHTNESS_ADDR 0x10
void Save_Brightness(unsigned char level) {
EEPROM_Write(BRIGHTNESS_ADDR, level);
}
unsigned char Load_Brightness(void) {
return EEPROM_Read(BRIGHTNESS_ADDR);
}CThis simple logic lets your device remember user preferences such as display brightness or temperature set-points.
Important Considerations
- Do not perform frequent writes in loops — EEPROM has limited write cycles.
- Use flags or buffers to avoid unnecessary write operations.
- Ensure interrupts are disabled during write operations to prevent corruption.
Code Example
//EEPROM of PIC18F ===========================================================
// Program: EEPROM Read and Write Example for PIC18F4550
// Compiler: XC8
// Author: Bitziga Technologies
//===========================================================
#include <xc.h>
// Configuration bits
#pragma config FOSC = HSPLL_HS // High-speed oscillator, PLL enabled
#pragma config WDT = OFF // Watchdog Timer disabled
#pragma config LVP = OFF // Low Voltage Programming disabled
#pragma config PBADEN = OFF // PORTB<4:0> digital on reset
#define _XTAL_FREQ 20000000 // 20 MHz Crystal Frequency
#define LED LATBbits.LATB0 // LED connected to RB0
#define BUTTON PORTBbits.RB1 // Push button on RB1
#define EEPROM_ADDR 0x10 // EEPROM address to store data
//-----------------------------
// Function Prototypes
//-----------------------------
void EEPROM_Write(unsigned char address, unsigned char data);
unsigned char EEPROM_Read(unsigned char address);
void Init_Ports(void);
//===========================================================
// Main Function
//===========================================================
void main(void)
{
unsigned char stored_data = 0;
Init_Ports(); // Initialize ports
// Read stored value from EEPROM on startup
stored_data = EEPROM_Read(EEPROM_ADDR);
// Display last stored value (0 or 1) on LED
LED = stored_data;
while (1)
{
// If button pressed, toggle LED and save to EEPROM
if (BUTTON == 0) // Active low button
{
__delay_ms(50); // Debounce delay
if (BUTTON == 0)
{
LED = !LED; // Toggle LED
EEPROM_Write(EEPROM_ADDR, LED); // Save state
while (BUTTON == 0); // Wait until release
}
}
}
}
//===========================================================
// Function: EEPROM_Write
// Description: Writes a byte to internal EEPROM
//===========================================================
void EEPROM_Write(unsigned char address, unsigned char data)
{
while (EECON1bits.WR); // Wait for previous write
EEADR = address; // Set address
EEDATA = data; // Set data
EECON1bits.EEPGD = 0; // Access data EEPROM
EECON1bits.CFGS = 0; // Access EEPROM not config
EECON1bits.WREN = 1; // Enable writes
INTCONbits.GIE = 0; // Disable interrupts
EECON2 = 0x55; // Required unlock sequence
EECON2 = 0xAA;
EECON1bits.WR = 1; // Start write
while (EECON1bits.WR); // Wait until complete
EECON1bits.WREN = 0; // Disable writes
INTCONbits.GIE = 1; // Enable interrupts
}
//===========================================================
// Function: EEPROM_Read
// Description: Reads a byte from internal EEPROM
//===========================================================
unsigned char EEPROM_Read(unsigned char address)
{
EEADR = address; // Set address
EECON1bits.EEPGD = 0; // Access data EEPROM
EECON1bits.CFGS = 0; // Access EEPROM not config
EECON1bits.RD = 1; // Start read
return EEDATA; // Return data
}
//===========================================================
// Function: Init_Ports
// Description: Initialize I/O ports for LED and button
//===========================================================
void Init_Ports(void)
{
TRISBbits.TRISB0 = 0; // RB0 as output (LED)
TRISBbits.TRISB1 = 1; // RB1 as input (Button)
LED = 0; // LED off initially
}CWorking Principle
- When the system starts, it reads the last saved LED state from EEPROM and updates the LED.
- Pressing the push button toggles the LED and stores the new state (0 or 1) in EEPROM.
- After a reset or power-off, the LED retains its last state because the value is fetched from EEPROM.
Output Observation
- Initially, the LED will reflect the stored state.
- Each button press toggles the LED and updates the EEPROM.
- After resetting the board, the LED restores the previous state automatically.
Applications
- Storing system flags or user preferences.
- Maintaining device mode (ON/OFF) across power cycles.
- Retaining calibration or configuration data.
Summary
This example demonstrates how to use the internal EEPROM of the PIC18F4550 to store data permanently. It’s an essential skill for embedded developers who need non-volatile memory in their designs.
Datasheet: EEPROM of PIC18F (PIC18F4550 Microcontroller)
Learn More
Do you want to go beyond just configuring the EEPROM of PIC18F and build complete projects?
🎓 Join our Complete Practical Video Course on PIC18F4550 Microcontroller
Get step-by-step guidance on USB, I²C, SPI, UART, ADC, and more — with real circuits and projects!
➡️ Start Learning Now at “Master PIC18F4550 Programming“
Complete Video Course on PIC18F4550 Microcontroller

Datasheet: EEPROM of PIC18F (PIC18F4550 Microcontroller)
💬Frequently Asked Questions (FAQ)
EEPROM (Electrically Erasable Programmable Read-Only Memory) is a non-volatile memory used to store data permanently, even after the power is turned off. It is ideal for saving user settings, calibration data, or device states.
The PIC18F4550 has 256 bytes of internal EEPROM memory, which can be accessed for both read and write operations using program code.
Writing too frequently can reduce the EEPROM’s lifespan because it has a limited number of write cycles (typically 100,000 writes). It’s recommended to use buffering or write only when data changes.
EEPROM is designed for storing small amounts of data that need frequent updates, while Flash memory stores the program code and is not typically used for variable data storage.
Yes, disabling interrupts during EEPROM writes ensures the correct sequence and prevents accidental corruption of data.
You can perform a read operation immediately after writing and compare the read value with the intended data to verify a successful write.
Yes, Proteus fully supports EEPROM simulation for PIC18F4550. You can observe the LED and button behavior as shown in the circuit diagram to verify your code functionality.
You’ll need MPLAB X IDE, XC8 Compiler, and optionally Proteus for circuit simulation. A programmer such as PICkit 3 or PICkit 4 can be used for real hardware programming.


