Interfacing to External EEPROM
From Mech
Using an external EEPROM can be useful for several different reasons. External EEPROMs also allow much more data to be stored than is available on the 18F4520. In addition, EEPROM saves state when power is cycled.
Circuit
We used a Microchip 24FC515 external EEPROM. (http://ww1.microchip.com/downloads/en/devicedoc/21673E.pdf)
Code
/* eeprom_rand_access.c Scott McLeod 03-05-2008 This program shows how to interface to an I2C extrenal Microchip EEPROM. This code is written for random reads and writes to the EEPROM */
#include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=20000000) #use i2c(MASTER, FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW) // use hardware i2c controller int8 EEPROM_WR = 0xA0; // I2C Address. 1010 0000. last bit = 0 => write command // First Nibble is fixed as 1010 (internal address); // Second Nibble is ABCD, // A = Block Set // B, C = Hardware Addresses (Configured when you Wire the CHIP) // D = (0 = write, 1 = read) int8 EEPROM_RD = 0xA1; // Same as EEPROM_WR except last bit = 1 for READ command
int read = 0; int data = 128; int16 loc; int temp = 0; void rand_write(int16 address, int data) { i2c_start(); // Claim I2C BUS i2c_write(EEPROM_WR); // Tell all I2C devices you are talking to EEPROM in WRITE MODE i2c_write(address>>8); // Address High Byte (0x00 - 0x) i2c_write(address); // Address Low Byte (0x00 - 0xAA) i2c_write(data); // Data to write i2c_stop(); // Release BUS delay_ms(25); // Let EEPROM Write Data } int rand_read(int16 address) { i2c_start(); // Claim I2C BUS i2c_write(EEPROM_WR); // Tell all I2C devices you are talking to EEPROM in WRITE MODE // (you are first writing to the EEPROM to set the address. Later you will read) i2c_write(address>>8); // Address High Byte (0x00 - 0x i2c_write(address); // Address Low Byte (0x00 - 0xAA) i2c_start(); // RESTART I2C BUS (necissary for microchip protocol) i2c_write(EEPROM_RD); // Tell all I2C you are talking to EEPROM in READ MODE. read = i2c_read(); // Read in the data i2c_read(0); // Read last byte with no ACK i2c_stop(); // release the bus return(read); } void main() { output_d(1); // Output a 1 for reference to start delay_ms(1000); // *Not necissary pause, just for debugging loc = 0x00; // Random Location in memory temp = 15; // Byte to write rand_write(loc, temp); // Random Write: rand_write(address, data)
output_d(255); delay_ms(1000); // *Not necissary pause, just for visual purposes
temp = 0; // Reset temp temp = rand_read(loc); // Random Read: rand_read(address); output_d(temp); // Output temp while(true) { } }