Go Down

Topic: SPI EEPROM Help (Read 987 times) previous topic - next topic

grandtippler

Hello,
I'm trying to interface an AT25256 EEPROM to my Arduino for a project but I'm having no luck. I can write the first 64 bytes no problem, but then when I write to address 64 it wraps around and writes to address 01 again.

To test my hardware I'm us the "Interfacing a Serial EEPROM Using SPI" code from the arduino site. http://arduino.cc/en/Tutorial/SPIEEPROM

I'm using an at25256 but the EEPROM from the example code I use is a AT25HP512. Could this be by problem?

This is my first go at SPI so I'm well out of my depth here, any help would be appreciated.

Code: [Select]
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
 for (int I=0;I<128;I++)
 {
   buffer[I]=I;
 }
}

char spi_transfer(volatile char data)
{
 SPDR = data;                    // Start the transmission
 while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
 {
 };
 return SPDR;                    // return the received byte
}

void setup()
{
 Serial.begin(9600);

 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device
 // SPCR = 01010000
 //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
 //sample on leading edge of clk,system clock/4 rate (fastest)
 SPCR = (1<<SPE)|(1<<MSTR);
 clr=SPSR;
 clr=SPDR;
 delay(10);
 //fill buffer with data
 fill_buffer();
 //fill eeprom w/ buffer
 digitalWrite(SLAVESELECT,LOW);
 spi_transfer(WREN); //write enable
 digitalWrite(SLAVESELECT,HIGH);
 delay(10);
 digitalWrite(SLAVESELECT,LOW);
 spi_transfer(WRITE); //write instruction
 address=0;
 spi_transfer((char)(address>>8));   //send MSByte address first
 spi_transfer((char)(address));      //send LSByte address
 //write 128 bytes
 for (int I=0;I<128;I++)
 {
   spi_transfer(buffer[I]); //write data byte
 }
 digitalWrite(SLAVESELECT,HIGH); //release chip
 //wait for eeprom to finish writing
 delay(3000);
 Serial.print('h',BYTE);
 Serial.print('i',BYTE);
 Serial.print('\n',BYTE);//debug
 delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
 //READ EEPROM
 int data;
 digitalWrite(SLAVESELECT,LOW);
 spi_transfer(READ); //transmit read opcode
 spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
 spi_transfer((char)(EEPROM_address));      //send LSByte address
 data = spi_transfer(0xFF); //get data byte
 digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
 return data;
}

void loop()
{
 eeprom_output_data = read_eeprom(address);
 Serial.print(eeprom_output_data,DEC);
 Serial.print('\n',BYTE);
 address++;
 if (address == 128)
   address = 0;
 delay(500); //pause for readability
}
 

aspartame

#1
Jan 15, 2009, 06:05 am Last Edit: Jan 15, 2009, 06:06 am by aspartame Reason: 1
From the AT25256 datasheet (http://www.datasheetcatalog.org/datasheet/atmel/doc0872.pdf):
"The AT25128/256 is capable of a 64-byte PAGE WRITE operation. After each byte of data is received, the six low order address bits are internally incremented by one; the high order bits of the address will remain constant. If more than 64 bytes of data are transmitted, the address counter will roll over and the previously written data will be
overwritten."

So, you'll have to send another Write command with a new address after each 64 Bytes of writing.

grandtippler

Thanks so much for your help on that, I looked and looked but still didn't get that I had to resend the address. It was all there in the datasheet, I know.

Thanks again for helping!!!

Go Up