ad space

How to Use EEPROM in PIC16F877A for Data Storage

When working on embedded projects with the PIC16F877A microcontroller, there are scenarios where you need to store data that persists even when the power is turned off. For instance, storing user settings, sensor calibration data, or non-volatile data is essential. This is where the EEPROM (Electrically Erasable Programmable Read-Only Memory) comes into play.

EEPROM in PIC16F877A

 Previous tutorials Write Read Sensor Data to External EEPROM with Arduino, Arduino Nano I2C EEPROM programming tutorial, Read Write to External EEPROM with Arduino, showed how to use external EEPROM with Arduino. Here, we will explore how to use the internal EEPROM in the PIC16F877A to store and retrieve data for your embedded projects.


What is EEPROM?

EEPROM is a type of non-volatile memory that allows the storage of data even after the power is removed. The PIC16F877A has 256 bytes of EEPROM that you can read from and write to, making it suitable for small data storage like configuration settings, device states, etc.


Why Use EEPROM?

  • Non-Volatile Storage: EEPROM retains data after power-off, unlike RAM, which is volatile.
  • Durability: EEPROM has limited write cycles, typically 1,000,000, but it's durable enough for most embedded applications.
  • Easy Access: PIC microcontrollers provide easy access to the EEPROM using built-in registers.

Accessing EEPROM in PIC16F877A

The PIC16F877A provides a set of registers for interacting with the EEPROM:

  • EECON1: Controls the EEPROM operations (write/erase).
  • EECON2: A necessary register for write operations (does not store actual data).
  • EEADR: The address register that holds the address of the byte in EEPROM you want to read/write.
  • EEDATA: The data register that holds the byte of data to be written or read from EEPROM.

Steps to Read and Write Data to EEPROM

  1. Writing Data to EEPROM:

    • Set the address where you want to store the data.
    • Load the data into the EEDATA register.
    • Set up write control and initiate the write process.
  2. Reading Data from EEPROM:

    • Set the address of the byte to be read in EEADR.
    • Start the read process and fetch the data from the EEDATA register.

Let’s look at some example code to read and write EEPROM data in the PIC16F877A.


Example: Writing Data to EEPROM

The following code writes a value to a specific address in EEPROM:

#include <xc.h>

#define _XTAL_FREQ 16000000 // Define clock frequency

// Configuration Bits
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

void EEPROM_Write(unsigned char address, unsigned char data) {
// Set up address and data
EEADR = address; // Set address to write to
EEDATA = data; // Load data into the EEPROM data register

// Required sequence for EEPROM write
EECON1bits.EEPGD = 0; // Access EEPROM data memory
EECON1bits.WREN = 1; // Enable write operations

// Disable interrupts
INTCONbits.GIE = 0;

// Required sequence for EEPROM write
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1; // Start the write operation

// Wait for write to complete
while (EECON1bits.WR);

// Re-enable interrupts
INTCONbits.GIE = 1;

EECON1bits.WREN = 0; // Disable write operations
}

Example: Reading Data from EEPROM

Here is how you can read data back from the EEPROM:

unsigned char EEPROM_Read(unsigned char address) {
// Set the address to read from
EEADR = address;
EECON1bits.EEPGD = 0; // Access EEPROM data memory
EECON1bits.RD = 1; // Initiate read operation

// Return the data from EEPROM
return EEDATA;
}


In this code:

  • The EEPROM_Read() function reads the byte of data stored at the specified EEPROM address.

Full Example: Storing and Retrieving Data

Below is a complete example of writing and then reading back a value from EEPROM.

#include <xc.h>

#define _XTAL_FREQ 16000000

// Configuration bits
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

// Function Prototypes
void EEPROM_Write(unsigned char address, unsigned char data);
unsigned char EEPROM_Read(unsigned char address);

void main() {
unsigned char readValue;

// Write value 0x37 to EEPROM address 0x10
EEPROM_Write(0x10, 0x37);

// Read the value from EEPROM address 0x10
readValue = EEPROM_Read(0x10);

// Store read value in PORTB for visualization (e.g., LEDs connected to PORTB)
TRISB = 0x00; // Set PORTB as output
PORTB = readValue; // Display the read value on PORTB LEDs

while(1);
}

void EEPROM_Write(unsigned char address, unsigned char data) {
EEADR = address;
EEDATA = data;
EECON1bits.EEPGD = 0; // Point to data memory
EECON1bits.WREN = 1; // Enable writes to EEPROM

// Required write sequence
INTCONbits.GIE = 0; // Disable interrupts
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1; // Start write
while(EECON1bits.WR); // Wait for completion
INTCONbits.GIE = 1; // Re-enable interrupts

EECON1bits.WREN = 0; // Disable EEPROM writes
}

unsigned char EEPROM_Read(unsigned char address) {
EEADR = address;
EECON1bits.EEPGD = 0; // Point to data memory
EECON1bits.RD = 1; // Initiate read
return EEDATA; // Return the value
}


Explanation of the Code:

  • EEPROM_Write(): Writes a single byte of data to the EEPROM at a specified address.
  • EEPROM_Read(): Reads a byte of data from the EEPROM at a specified address.
  • PORTB: Displays the read value on PORTB, which could be connected to LEDs for visualization in this example.

Applications of EEPROM in Embedded Systems:

  • Storing Device Settings: You can store user preferences or device configurations in EEPROM.
  • Sensor Calibration: Save sensor calibration data so it persists even after a power cycle.
  • Counter Storage: Store the count of events or usage metrics.
  • Data Logging: Store logged data when the microcontroller cannot communicate with a master device immediately.

Conclusion

The internal EEPROM in the PIC16F877A is an invaluable resource for storing non-volatile data in your embedded applications. With just a few lines of code, you can write and read data to and from EEPROM, making it ideal for saving configurations, sensor data, or any small amount of data you need to persist across resets.

EEPROM is durable and relatively simple to use, but keep in mind the write cycle limits. Plan your use cases so that you do not exceed the write endurance for critical applications.

Further Reading:

Post a Comment

Previous Post Next Post