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:
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:
- EEDATA – 8-bit register, works as a buffer, where data is placed.
- EEADR – 7 bit register, there is an address placed for read/write operation to a single byte of EEPROM.
- Software register EECON2 – register used only for writing operation, u have to write the next sequence for successful operation:
EECON2=0x55; EECON2=0xAA;
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:
- Write wanted address to EEADR.
- Set RD = “1”.
- Data has been collected in the EEDAT and is ready for use.
Step-by-step writing to EEPROM:
- Write wanted address to EEADR.
- Write data to EEDAT.
- Set WREN = “1”.
- Write sequence to EECON2 (0x55 and 0хАА).
- Set WR = “1”.
Also, the datasheet highly recommended to shut down interrupts for time when reading/writing operation occurs.
Example:
#include <htc.h> #define _XTAL_FREQ 4000000 __CONFIG(MCLRDIS & UNPROTECT & WDTDIS & LVPDIS & HS); 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) { __delay_ms(100); 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) { GIE=0; EEADR=adres; EEDATA=data; WREN=1; EECON2=0x55; EECON2=0xAA; WR=1; GIE=1; }
Example video:
Here is PORTB state:
And the EEPROM state at the moment:
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.