Pic Lab, PIC16, Experiment #12, EEPROM

Goal: To write and read EEPROM

What we have: PIC16f628a and a 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:

from the mikroe resourse

EEPGD – don’t use 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 initialization
• 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 a logic high level, they reset to logic low automatically.

There are some additional registers:

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


And, of course, there is an interrupt event that could be generated, flag EEIF has a 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 been collected in the EEDAT and is ready for use.

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, the 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 the 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 built-in functions is very straightforward, so I even don’t place it here.

The sources.

Leave a Reply

Your email address will not be published.