NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Adding EEPROM

January 05, 2011
by jgreen6800
jgreen6800's Avatar

I would like to interface my MCU with some sort of non-volatile memory to record values from my ADC. Does anyone have any experience interfacing the MCU with EEPROM or other non-volatile memory? I have never done anything like this before. Is there any good reference material out there for a newbie? Thanks for your input.

Jim

January 06, 2011
by Rick_S
Rick_S's Avatar

I was playing around with an external 24C128N EEPROM when I was messing around with the WII Nunchuck control. This is an 128K I2C EEPROM. I believe this is working code... but I haven't used it in a while and was working on something else. It may have even been part of the sample code in the library download... so I take no credit for it other than the NK additions :). I just used this to make sure the I2C routines were working. This code will also require the I2C library published by Peter Fleury. You can download it from his website HERE. This should work with most I2C EEPROMS with little change other than maybe addressing.

Hope this helps,

Rick

#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "i2cmaster.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

#define MEM_ADR 0xA0

// Write to external eeprom 1 byte at a time

uint8_t Exep_Write(uint16_t Mem_Loc, int8_t Data)
  {
    uint8_t ret = i2c_start(MEM_ADR+I2C_WRITE);
        if ( ret ) {
        /* failed to issue start condition, possibly no device found */
        i2c_stop();
        PORTB=0xff;                            // activate all 8 LED to show error */
        return 0;
    }else {
        delay_us(500);   // pause a moment

        /* issuing start condition ok, device accessible */
        // set eeprom address and data
        i2c_write(Mem_Loc);         // Send Low 8 bit of I2C Address                   
        i2c_write(Mem_Loc>>8);      // Send High 8 bit of I2C Address

        i2c_write(Data);            // Send data

        i2c_stop();                 // Stop Transmission
        delay_us(500);              // pause a moment
        PORTB = 0x00;               // turn off led - no error
    }
    return 1;
  }

// Read from external eeprom 1 byte at a time

uint8_t Exep_Read(uint16_t Mem_Loc)
  {
    i2c_start_wait(MEM_ADR+I2C_WRITE);     // set device address and write mode
    i2c_write(Mem_Loc);                    // Send Low 8 bit of I2C Address
    i2c_write(Mem_Loc>>8);                 // Send High 8 bit of I2C Address
    i2c_rep_start(MEM_ADR+I2C_READ);       // set device address and read mode
    uint8_t temp = i2c_readNak();          // read one byte
    i2c_stop();

    return temp;                            // return byte read
  }

int main(void)
{
    uint8_t nc_data[6];

    uint16_t Location;

    int8_t Data_to_send;

    for(int i=0;i<6;i++)
        {
            nc_data[i]=0;
        }

    DDRB  = 0xff;                              // use all pins on port B for output 
    PORTB = 0x00;                              // (active high LED's )

    i2c_init();                                // init I2C interface

    lcd_init();                                 // fire up the LCD
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_home();

    for(uint8_t i=0;i<6;i++)
    {
        Location = i;
        Data_to_send = i*i;
        while(!Exep_Write(Location,Data_to_send))
            {
            PORTB=0xff;
            }
        PORTB=0x00;
    }

    while(1){

            for(uint8_t i=0;i<6;i++)
            {
            Location = i;
            nc_data[i] = Exep_Read(Location);
            lcd_line_one();

            fprintf_P(&lcd_stream, PSTR("Read data %3u"),nc_data[i]);
            delay_ms(500);
            }

        }

    for(;;);

    return 0;

}
January 06, 2011
by jgreen6800
jgreen6800's Avatar

Thanks Rick! Between your code and Mike's help with the hardware selection (it's posted under the data logging thread), I think I'm off to a great start. I didn't realize that the data would be written and read from the PROM serially (if that's a word). I thought you would do it through a parallel interface but I guess that would use many more wires for the data bus. I'm going to go over the LED Array project example. I believe it's the same protocol/interface method. Thanks Again,

Jim

January 06, 2011
by Rick_S
Rick_S's Avatar

Actually the eeprom Mike was referring to was an SPI type. The code posted above is for an I2C type. The I2C is only a Two Wire Interface (called TWI) on the chip. I used that because the eeprom I had was a pull from an old cell phone. The nice thing about I2C is it uses two wires for everything where SPI needs 4. This gives you more available pins for other tasks.

Rick

January 10, 2011
by jgreen6800
jgreen6800's Avatar

Thanks for your clarification, Rick! I was heading down the wrong path. I'll have to do some research on the SPI protocol (I guess it is a difference in protocol ?). I would appreciate any suggestions/comments.

Jim

January 10, 2011
by Rick_S
Rick_S's Avatar

Are you already tied to an SPI device? If not, the I2C ones work as just as well.

January 14, 2011
by jgreen6800
jgreen6800's Avatar

I haven't purchased any hardware yet, so I'm not tied to SPI. I think you're right, it would be easier to use I2c instead of trying to come up with the code for SPI. My hope is this isn't too difficult and the data sheets are of some help.

Thanks again, Rick!, Jim

March 08, 2013
by scootergarrett
scootergarrett's Avatar

I have an EEPROM question that could go in this forum, most of the suppliers only sell EEPROM chips up to 1Mbit or so example is this typical for an upper limit for EEPROM? What if I need more memory? Will a FLASH memory chip work or do those typically run to fast? Basically I need a lot of memory (approx 1GB or more) on an external chip the nerd kit can communicate with, and have it come in a small package preferable a DIP and a SOIC so I can develop the circuit then make a tiny version. If it can be volatile or not is still up in the air, I’m going to do some button cell battery testing soon.

Thanks

March 08, 2013
by Ralphxyz
Ralphxyz's Avatar

Hi scootergarrett , this might not help but using I2C you can use 8 EEPROMs I believe.

If you need to store 1 gig why not use a SD card?

Ralph

June 18, 2013
by dvdsnyd
dvdsnyd's Avatar

Hi Guys, I know this thread is pretty old, but I was wondering if someone could explain a block of code to me? This block starts at line 75 of Rick's original post. Specifically I am confused with the while loop of line 5. What does the exclamation mark do? How can you have a while loop on a function? I am thinking it is checking something, then executing the write?

for(uint8_t i=0;i<6;i++)
{
    Location = i;
    Data_to_send = i*i;
    while(!Exep_Write(Location,Data_to_send))
        {
        PORTB=0xff;
        }
    PORTB=0x00;
}

Thanks, Dave

June 18, 2013
by esoderberg
esoderberg's Avatar

Dave,

The ! is a logical NOT. For ref : Operators in C

Eric

June 19, 2013
by dvdsnyd
dvdsnyd's Avatar

Eric, Thanks for your response. I will take a look at the link closer later.

I guess what I am really wanting to know is how can you have a while loop on a function.

This code is executing the while loop when Exep_Write() is NOT equal to what? or Not sending back what?

Sorry if this is blatently obvious....

Thanks again for all the help Dave

June 19, 2013
by esoderberg
esoderberg's Avatar

David,

Having not run or studied Rick's code closely, here's my cut on your questions. The the function, Exep_Write(uint16_t Mem_Loc, int8_t Data), is returning either a one or a zero. For logical operations this works out to True and False. In general, any non-zero value will be evaluated as True and zero will be False. So for the following example:

while(Function_that_returns_one_or_zero)

when one is returned the loop runs, when a zero is returned you break out. Because Rick's code uses the logical NOT this is reversed, when the function returns a zero the loop runs, when a one is returned you break out.

Eric

June 19, 2013
by dvdsnyd
dvdsnyd's Avatar

Thanks Eric, As I was thinking, I totally overlooked the return 0 and return 1 in the code. Thanks again for your explanation!

David

June 19, 2013
by dvdsnyd
dvdsnyd's Avatar

Thanks Eric, As I was thinking, I totally overlooked the return 0 and return 1 in the code. Thanks again for your explanation!

David

Post a Reply

Please log in to post a reply.

Did you know that a NerdKit can take control of a remote-controlled car? Learn more...