Really hope someone can help me as to where I have gone wrong in my code. I am a 25LC1024 micro chip and I'm trying to store a 16 bit integer value into 2 bytes and then reading the 2 bytes and putting them back together. Any help would be much appreciated, THANKS.
// 25LC1024 1Mbit SPI interface
//
// Device pin connections:
// 1 = CS (Chip Select) (from Arduino)
// 2 = SO (Master In Slave Out) (from Arduino)
// 3 = +5V (WP) (from Arduino)
// 4 = 0V (Ground) (from Arduino)
// 5 = SI (Master Out Slave In) (from Arduino)
// 6 = SCK (from Arduino)
// 7 = +5V HOLD (from Arduino)
// 8 = +5V Vcc (from Arduino)
//
// This file uses the SPI library and produces higher oscillation rates than the manual methods
// for the Uno: SS/CS = pin 10, MOSI/SI = pin 11, SCK/clock = pin 13, MISO/SO = pin = 12
//
#define WRITE 2
#define READ 3
#define WREN 6
#include <SPI.h>
unsigned int readvalue;
void setup()
{
Serial.begin(9600);
Serial.println("--------------");
Serial.println(SS); // chip select
Serial.println(MOSI); // master out, slave in
Serial.println(MISO); // master in, slave out
Serial.println(SCK); // clock
Serial.println("--------------");
// set up to match device datasheet
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed
SPI.begin(); // sets up pin modes etc.
// Enable writing
digitalWrite(SS, LOW);
SPI.transfer(WREN);
digitalWrite(SS, HIGH);
writing(50, 34); // data value, address
readvalue = reading(34);
Serial.print("Read Data = ");
Serial.println(readvalue);
}
void writing(unsigned int outval, unsigned long address)
{
unsigned char low, high;
unsigned long lowaddress = address + address;
unsigned long highaddress = lowaddress + 1;
low = outval & 0x00FF;
high = (outval >> 8) & 0x00FF;
// Write One Value to One Address
digitalWrite(SS, LOW);
SPI.transfer(WRITE); // write instruction
SPI.transfer((lowaddress >> 16) & 255);
SPI.transfer((lowaddress >> 8) & 255);
SPI.transfer(lowaddress & 255);
SPI.transfer(low);
digitalWrite(SS, HIGH);
// Write One Value to One Address
digitalWrite(SS, LOW);
SPI.transfer(WRITE); // write instruction
SPI.transfer((highaddress >> 16) & 255);
SPI.transfer((highaddress >> 8) & 255);
SPI.transfer(highaddress & 255);
SPI.transfer(high);
digitalWrite(SS, HIGH);
delay(100);
}
unsigned int reading (unsigned long address)
{
unsigned char low, high;
unsigned long lowaddress = address + address;
unsigned long highaddress = lowaddress + 1;
unsigned int finaloutput = 0;
// Read One Value from One Address
digitalWrite(SS, LOW);
SPI.transfer(READ); // read instruction
SPI.transfer((lowaddress >> 16) & 255);
SPI.transfer((lowaddress >> 8) & 255);
SPI.transfer(lowaddress & 255);
low = SPI.transfer(lowaddress);
digitalWrite(SS, HIGH);
digitalWrite(SS, LOW);
SPI.transfer(READ); // read instruction
SPI.transfer((highaddress >> 16) & 255);
SPI.transfer((highaddress >> 8) & 255);
SPI.transfer(highaddress & 255);
high = SPI.transfer(highaddress);
digitalWrite(SS, HIGH);
finaloutput = (high << 8) | low;
return finaloutput;
}
void loop()
{
}
Sorry, probably should have stated that too, haha.
The read value printed to the Serial Monitor is always random, usual a very high number such as 65330. Not sure the reading functions manages to do this. Both low and high values are always read as 255
When it always reads everything as 255 it usually indicates a wiring error.
But, if for any reason it doesn't write the value into the EEPROM, then you'll get 255 back anyway because that is the initial state of the erased EEPROM.
I've checked the wiring 3-4 times and it definitely right.
When I write one integer and to a single address the code works however when put through an array this is when the problem occurs. Trying to write an array of integers using a 'for while loop' to a number of addresses causes funny results. The value saved previously in the address is from writing one value at a time to a single address. If I haven't written something to a single address, thats when 65536 occurs? I think I've neated my code up thought but still having the same issue of writing an array one numbers and reading them back again
// 25LC1024 1Mbit SPI interface
//
// Device pin connections:
// 1 = CS (Chip Select) (from Arduino)
// 2 = SO (Master In Slave Out) (from Arduino)
// 3 = +5V (WP) (from Arduino)
// 4 = 0V (Ground) (from Arduino)
// 5 = SI (Master Out Slave In) (from Arduino)
// 6 = SCK (from Arduino)
// 7 = +5V HOLD (from Arduino)
// 8 = +5V Vcc (from Arduino)
//
// This file uses the SPI library and produces higher oscillation rates than the manual methods
// for the Uno: SS/CS = pin 10, MOSI/SI = pin 11, SCK/clock = pin 13, MISO/SO = pin = 12
//
#define WRITE 2
#define READ 3
#define WREN 6
#include <SPI.h>
unsigned int values[10] = {0,4,6,7,3,2,4,5,5,7};
unsigned long masteraddress = 5, time1, time2, samplerate, readtime;
float timeseconds;
unsigned int readvalue;
byte invalue, invalue2;
void setup()
{
Serial.begin(9600);
// set up to match device data sheet
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed
SPI.begin(); // sets up pin modes etc.
// Enable writing
digitalWrite(SS, LOW);
SPI.transfer(WREN);
digitalWrite(SS, HIGH);
writing(masteraddress, 666); // address, data value
Serial.print("Read Time = ");
time1 = micros(); // Gather time in micro seconds before reading 10,00 values
for(int i = 0; i < 10000; i++)
{
readvalue = reading(i);
}
time2 = micros(); // Gather time in micro seconds after reading 10,00 values
readtime = time2 - time1; // calculates time in micro seconds to read 10,000 values
Serial.println(readtime);
timeseconds = readtime / 1000000; // Converts micro seconds into seconds
samplerate = 10000 / timeseconds; // Sample rate = Number of values read / Length of time in seconds
Serial.print("Time in seconds = ");
Serial.println(timeseconds);
Serial.print("Sample rate = ");
Serial.println(samplerate);
Serial.print("Read value = ");
Serial.println(readvalue,DEC);
}
void writing(unsigned long address, unsigned int inputval)
{
unsigned char low, high;
unsigned long lowaddress = address * 2;
unsigned long highaddress = lowaddress + 1;
low = inputval & 0x00FF;
high = (inputval >> 8) & 0x00FF;
digitalWrite(SS, LOW);
SPI.transfer(WRITE); // write instruction
// Write low byte first
SPI.transfer((lowaddress >> 16) & 255);
SPI.transfer((lowaddress >> 8) & 255);
SPI.transfer(lowaddress & 255);
SPI.transfer(low);
// Write high byte second
SPI.transfer((highaddress >> 16) & 255);
SPI.transfer((highaddress >> 8) & 255);
SPI.transfer(highaddress & 255);
SPI.transfer(high);
digitalWrite(SS, HIGH);
}
unsigned int reading(unsigned long address)
{
unsigned char low, high;
unsigned long lowaddress = address * 2;
unsigned long highaddress = lowaddress + 1;
unsigned int finaloutput;
digitalWrite(SS, LOW);
SPI.transfer(READ); // read instruction
// Read the low byte first
SPI.transfer((lowaddress >> 16) & 255);
SPI.transfer((lowaddress >> 8) & 255);
SPI.transfer(lowaddress & 255);
low = SPI.transfer(lowaddress);
// Read the high byte second
SPI.transfer((highaddress >> 16) & 255);
SPI.transfer((highaddress >> 8) & 255);
SPI.transfer(highaddress & 255);
high = SPI.transfer(highaddress);
finaloutput = (high << 8) | low;
digitalWrite(SS, HIGH);
return finaloutput;
}
void loop()
{
}
I've decided to try and do a page write instead and it worked and with the help you have given me I've adapted it however this code did work but all of sudden stopped working.
// 25LC1024 1Mbit SPI interface
//
// Device pin connections:
// 1 = CS (Chip Select) (from Arduino)
// 2 = SO (Master In Slave Out) (from Arduino)
// 3 = +5V (WP) (from Arduino)
// 4 = 0V (Ground) (from Arduino)
// 5 = SI (Master Out Slave In) (from Arduino)
// 6 = SCK (from Arduino)
// 7 = +5V HOLD (from Arduino)
// 8 = +5V Vcc (from Arduino)
//
// This file uses the SPI library and produces higher oscillation rates than the manual methods
// for the Uno: SS/CS = pin 10, MOSI/SI = pin 11, SCK/clock = pin 13, MISO/SO = pin = 12
//
#define WRITE 2
#define READ 3
#define WREN 6
#define SSMEMORY 9
#include <SPI.h>
void setup()
{
Serial.begin(9600);
pinMode(SSMEMORY, OUTPUT);
digitalWrite(SSMEMORY, HIGH);
Serial.println("--------------");
Serial.println(SSMEMORY); // chip select
Serial.println(MOSI); // master out, slave in
Serial.println(MISO); // master in, slave out
Serial.println(SCK); // clock
Serial.println("--------------");
// set up to match device datasheet
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
SPI.setClockDivider(SPI_CLOCK_DIV2); // max clock is 20MHz, so can set high speed
SPI.begin(); // sets up pin modes etc.
for (int i = 0; i < 5; i++)
{
writing(i, i); // data value, address
}
delay(100);
Serial.print("\n");
for(unsigned long i = 0; i < 5; i++)
{
unsigned int readvalue = reading(i);
Serial.print("READ = ");
Serial.println(readvalue);
Serial.print("\n");
}
}
void writing(unsigned int outval, unsigned long address)
{
unsigned char low, high;
address = address + address;
low = outval & 0x00FF;
high = (outval >> 8) & 0x00FF;
Serial.print("Write LOW Data = ");
Serial.println(low, DEC);
Serial.print("Write HIGH Data = ");
Serial.println(high, DEC);
// Write One Value to One Address
// Enable writing
digitalWrite(SSMEMORY, LOW);
SPI.transfer(WREN);
digitalWrite(SSMEMORY, HIGH);
digitalWrite(SSMEMORY, LOW);
SPI.transfer(WRITE); // write instruction
SPI.transfer((address >> 16) & 255);
SPI.transfer((address >> 8) & 255);
SPI.transfer(address & 255);
SPI.transfer(low);
SPI.transfer(high);
digitalWrite(SSMEMORY, HIGH);
}
unsigned int reading (unsigned long address)
{
unsigned char low, high;
address = address + address;
unsigned int finaloutput;
// Read One Value from One Address
digitalWrite(SSMEMORY, LOW);
SPI.transfer(READ); // read instruction
SPI.transfer((address >> 16) & 255);
SPI.transfer((address >> 8) & 255);
SPI.transfer(address & 255);
low = SPI.transfer(0);
high = SPI.transfer(0);
digitalWrite(SSMEMORY, HIGH);
Serial.print("Read LOW Data = ");
Serial.println(low, DEC);
Serial.print("Read HIGH Data = ");
Serial.println(high, DEC);
finaloutput = (high << 8) | low;
return finaloutput;
}
void loop()
{
}
In my setup I am also trying to use a DAC. Once I managed to get my code working for the DAC through using digital pin 9 as its OUTPUT for chip select, the pin 10 did not work any more for the external memory.
The result given for the the read value is always 65536 at every address. WHAT IS HAPPENING? I didn't change anything. I have checked the wiring... again and again but I swear its all correct.
I'm pretty sure you have to call SPI.begin before doing anything else. Otherwise your setup of bitorder etc. will be overridden by whatever default is set by SPI.begin.
The value of 65535 (not 65536?) is a 16-bit word with all ones which is what you get if you read two bytes which have been erased (or deliberately set to 0xFFFF).
Write timing can be critical with EEPROMS. I've had some fun recently getting an I2C 24LC1026 working properly.
The 25lc1024 datasheet has this about writing:
While the write is in progress, the Status Register may
be read to check the status of the WPEN, WIP, WEL,
BP1 and BP0 bits (Figure 2-6). A read attempt of a
memory array location will not be possible during a
write cycle. When the write cycle is completed, the
write enable latch is reset.
It is possible that it is still writing one byte when you try to write or read another. After the data has been written you'll have to check the status register to be sure that the write has completed.