Experiment #12. Work with EEPROM

Goal: To write and read EEPROM

What we have: PIC16f628a and simple devboard.

Microcontroller PIC16f628a has 128 bytes of EEPROM memory on board, not too much but we have what we have. Hi-tech PICC compiler has internal functions for work with EEPROM, but here I’m going to make some my personal functions.

Let’s look at the EECON1 register:


EEPGD – don’t used in the PIC16f628a
WRERR – error flag
• 1 – error has occurred
• 0 – operation done without errors
WREN – Permission of writing to EEPROM
• 1 – allowed
• 0 – not allowed
WR – control bit of writing
• 1 – Writing intitialization
• 0 – Writing is finished
RD – control bit of reading
• 1 – Reading initialization
• 0 – Reading is finished

*Bits WR and WD can be installed only at logic high level, they resets to logic low automatically.

There are some additional registers:

  1. EEDATA – 8 bit register, works as a buffer, where data placed.
  2. EEADR – 7 bit register, there is address placed for read/write operation to single byte of EEPROM.
  3. Software register EECON2 – register uses only for writing operation, u have to write the next sequence for successful operation:


And, of course, there is inerrupt event could be generated, flag EEIF has logic high value if writing operation was successfull.

Step by step reading from EEPROM:

  1. Write wanted address to EEADR.
  2. Set RD = “1”.
  3. Data has collected in the EEDAT and ready for using.

Step by step writing to EEPROM:

  1. Write wanted address to EEADR.
  2. Write data to EEDAT.
  3. Set WREN = “1”.
  4. Write sequence to EECON2 (0x55 and 0хАА).
  5. Set WR = “1”.

Also, datasheet highly recommended to shut down interrupts for time when reading/writing operation occurs.


#include <htc.h>
#define _XTAL_FREQ 4000000

unsigned char eeprom_read_my(unsigned char adres);                      
unsigned char eeprom_write_my(unsigned char data, unsigned char adres);  

void main() {
 unsigned char temp=0;
 CMCON = 0x07;               // shut down all comparators
 TRISA = 0xFF;
 TRISB = 0x00;
 temp = eeprom_read_my(0x07); // read wanted address

 for (;;) {
    PORTB = temp;                // value from EEPROM to PORTB
            if (!RA1) {
                             if (!RA1) {
                                       if (temp < 240) {                    // Write some values with step 16
                                                       temp = temp + 16;
                                                       eeprom_write_my(temp, 0x07);
                                                       } else {
                                                               temp = 16;
                                                               eeprom_write_my(temp, 0x07);



unsigned char eeprom_read_my(unsigned char adres) {
                                                 EEADR = adres;
                                                 RD = 1;
                                                 return EEDATA;


unsigned char eeprom_write_my(unsigned char data, unsigned char adres) {


Example video:

Here is PORTB state:


And EEPROM state at the moment:

eeprom status

There is 0х50 = 0b01010000 number at 0х07 address(B4 = 1 and B6 = 1 on the last picture).

Using of built-in functions is very straightforward, so I even don't place it here.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.