SRAM SPI 1Mbit @ Mega2560

Ich hab mir folgendes organisiert:
SRAM 1Mbit 2,5V 20MHz SPI/SDI/SQI DIP8
http://de.rs-online.com/web/p/speicherbausteine-sram/7697345/

laut Datenblatt kann er bis 5,5V ab daher hab ich ihn direkt angeschlossen.

den code hab ich von hier Gammon Forum : Electronics : Microprocessors : Connecting SRAM to your microprocessor using SPI

#include <SPI.h>

#define SRAM_DEVICE 53  // SRAM on pin 10

// 23A256 commands

#define SRAM_READ  0b011  // Read data from memory array beginning at selected address
#define SRAM_WRITE 0b010  // Write data to memory array beginning at selected address
#define SRAM_RDSR  0b101  // Read STATUS register
#define SRAM_WRSR  0b001  // Write STATUS register

// operation modes (status register)

#define SRAM_BYTE_MODE 0b00000000  // Byte mode (default operation) 
#define SRAM_PAGE_MODE 0b10000000  // Page mode
#define SRAM_SEQN_MODE 0b01000000  // Sequential mode
#define SRAM_RSVD_MODE 0b11000000  // Reserved
#define SRAM_HOLD_MODE 0b00000001  // Set this bit to DISABLE hold mode

// setup SRAM device by turning into sequential mode
void sram_setup (const byte device)
{
  digitalWrite (device, LOW);   // select device 
  SPI.transfer (SRAM_WRSR); 
  SPI.transfer (SRAM_SEQN_MODE); 
  digitalWrite (device, HIGH);  // deselect device
}  // end of sram_setup

// write 'length' bytes from 'data' to device at address 'address'
void sram_write (const byte device, unsigned int address, byte * data, unsigned int length)
{
  if (length == 0)  // don't bother if nothing to do
     return;
     
  digitalWrite (device, LOW);  
  SPI.transfer (SRAM_WRITE);     // write mode
  SPI.transfer (address >> 8);   // high-order address byte
  SPI.transfer (address & 0xFF);   // low-order address byte
  for ( ; length ; --length)
    SPI.transfer (*data++);     // data byte
  digitalWrite (device, HIGH);  // deselect device
}  // end of sram_write

// read 'length' bytes into 'data' to device from address 'address'
void sram_read (const byte device, unsigned int address, byte * data, unsigned int length)
{
  if (length == 0)  // don't bother if nothing to do
     return;

  digitalWrite (device, LOW);     // select device
  SPI.transfer (SRAM_READ);       // read mode
  SPI.transfer (address >> 8);    // high-order address byte
  SPI.transfer (address & 0xFF);  // low-order address byte
  for ( ; length ; --length)
    *data++ = SPI.transfer (0);     // data byte
  digitalWrite (device, HIGH);    // deselect device
}  // end of sram_write

void setup (void)
{
  Serial.begin (9600);
  SPI.begin ();    
  sram_setup (SRAM_DEVICE);
}

char test [] = "hello, world";

void loop (void)
{
 sram_write (SRAM_DEVICE, 100, (byte *) test, sizeof test);
 
 char buf [100];
 
 sram_read (SRAM_DEVICE, 100, (byte *) buf, sizeof buf);

 Serial.println (buf);
 delay (1000);
 
}

die Commands und Register sind laut Datenblatt die selben, aber als Ergebniss erhalte ich auf dem Monitor nur:
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿé je Durchlauf

ich nutze einen Mega2560

hat jemand ne idee warum das nicht passt?

Unbenannt.bmp (884 KB)

#define SRAM_DEVICE 53  // SRAM on pin 10

Du solltest den Kommentar auch anpassen, wenn Du den Wert veränderst, sonst weiss der Leser nie, was nun eigentlich gewünscht war.

char test [] = "hello, world";

void loop (void)
{
 sram_write (SRAM_DEVICE, 100, (byte *) test, sizeof test);

 char buf [100];

 sram_read (SRAM_DEVICE, 100, (byte *) buf, sizeof buf);

 Serial.println (buf);
 delay (1000);

}

Du schreibst 12 Zeichen und liest dann 100 ein, ohne Dich um die Terminierung zu kümmern. Dann gibst Du diese Zeichenkette aus, ohne eine entsprechende End-Marke eingefügt zu haben.

Dein Chip hat 128kB Speicher, Du adressierst aber mit 16-bit, womit Du aber nur 64kB erreichen kannst. Laut Datenblatt muss die Adresse auch 24-bit lang sein. Somit müsstest Du Deine Schreib-/Lese-Routinen enstprechend anpassen.

Hmm, OK danke. Ich dachte mit copy&paste wäre das erledigt nachdem die befehle gleich sind, aber wohl doch nicht. Ich kenn mich mit der Speicheranbindung so überhaupt nicht aus, kann mir jemand helfen den Code so umzubasteln, dass er für den Speicherchip funktioniert?

hab jetzt mal die addressierung angepasst(und hoff mal das es stimmt) und auch der einfachheithalber auf bytemodus gestellt und nur testweise 1 byte schreiben und wieder lesen wollen. Allerdings funktioniert die Sache irgendwie immer noch nicht.

#include <SPI.h>

#define SRAM_DEVICE 53  // SRAM on pin 53

// 23LC1024 commands

#define SRAM_READ  0b00000011  // 0x03 Read data from memory array beginning at selected address
#define SRAM_WRITE 0b00000010  // 0x02 Write data to memory array beginning at selected address
#define SRAM_RDSR  0b00000101  // 0x05 Read STATUS/MODE register
#define SRAM_WRSR  0b00000001  // 0x01 Write STATUS/MODE register

// operation modes (status register)

#define SRAM_BYTE_MODE 0b00000000  // 0x00 Byte mode (default operation) 
#define SRAM_PAGE_MODE 0b10000000  // 0x80 Page mode
#define SRAM_SEQN_MODE 0b01000000  // 0x40 Sequential mode
#define SRAM_RSVD_MODE 0b11000000  // 0xC0 Reserved
#define SRAM_HOLD_MODE 0b00000001  // 0x01 Set this bit to DISABLE hold mode


byte test = 20;
unsigned long testaddress=100;
byte outputvar;



void setup (void)
{
  Serial.begin (115200);
  SPI.begin ();    
  SPI.setBitOrder (MSBFIRST );            //MSB first
  SPI.setClockDivider(SPI_CLOCK_DIV2);    //SPI clock 8MHz
  SPI.setDataMode(SPI_MODE3);             // SPI Mode3 (1,1)
  
  pinMode(SRAM_DEVICE, OUTPUT);          //chipselector pin
  
  sram_setup (SRAM_DEVICE);
  Serial.println ("end setup\n");
}




void loop (void)
{
 sram_write (SRAM_DEVICE, testaddress, test);
 sram_read (SRAM_DEVICE, testaddress, outputvar);
 Serial.println (outputvar);
 
 delay (3000);
}



// setup SRAM device by turning into sequential mode
void sram_setup (const byte device)
{
  digitalWrite (device, LOW);   // select device 
  SPI.transfer (SRAM_WRSR); 
  SPI.transfer (SRAM_BYTE_MODE); 
  digitalWrite (device, HIGH);  // deselect device
}  // end of sram_setup




// write 'length' bytes from 'data' to device at address 'address'
void sram_write (const byte device, unsigned long address, byte data)
{
  digitalWrite (device, LOW);              // select device
  SPI.transfer (SRAM_WRITE);               // write mode
  byte address1=address>>16;
  byte address2=address>>8;
  byte address3=address;
                                           // mask last 8 bit
  SPI.transfer (address1);                 // high-order address byte (23-16)
  SPI.transfer (address2);                 // mid-order address byte (15-8)
  SPI.transfer (address3);                 // low-order address byte (7-0)
  SPI.transfer (data);                     // data byte
  digitalWrite (device, HIGH);             // deselect device
  Serial.println ("write");
}  // end of sram_write




// read 'length' bytes into 'data' to device from address 'address'
void sram_read (const byte device, unsigned long address, byte data)
{
  digitalWrite (device, LOW);              // select device
  SPI.transfer (SRAM_READ);                // read mode
  byte address1=address>>16;
  byte address2=address>>8;
  byte address3=address;
                                           
  SPI.transfer (address1);                 // high-order address byte (23-16)
  SPI.transfer (address2);                 // mid-order address byte (15-8)
  SPI.transfer (address3);                 // low-order address byte (7-0)
  data = SPI.transfer (0);                 // read SPI in data byte
  digitalWrite (device, HIGH);             // deselect device
  Serial.println ("read");
}  // end of sram_write

hi,

ich weiß jetzt nicht, wie das in C ist, aber das mit der parameter über- und rückgabe kommt mir seltsam vor.

versuch mal statt;
Serial.println (“read”);
ein
Serial.println (data);
an gleicher stelle.

gruß stefan

Das ist wohl eher nur ein kleiner Testausschrieb.

Aber Stefan hat schon Recht:

sram_read (SRAM_DEVICE, testaddress, outputvar); // geht so nicht.

Wenn outputvar beschrieben werden soll, kannst du sram_read nicht einfach dessen Wert übergeben.

in C übergibt man die Adresse von outputvar:

sram_read (SRAM_DEVICE, testaddress, & outputvar); 
...

void sram_read (const byte device, unsigned long address, byte* pdata) {
// überall data durch *pdata ersetzen...
}

In c++ gibts auch referenzen, aber das wird, wenn pointer ein Problem sind, evtl. eher noch verwirrender.

hi,

Das ist wohl eher nur ein kleiner Testausschrieb.

ja, aber es hat ihm der “echtausschrieb” gefehlt…
wenn er das ersetzt, kann er mal sehen, ob das lesen funkt. pointer wollte ich ihm (und mir) vorerst ersparen. das muß ich selber immer erst nachschlagen, weil ich’s kaum verwende.

gruß stefan

ok, danke Jungs. hat prima funktioniert.
kann schreiben und lesen einzelner Bytes.

für alle anderen die es interessiert hier nochmal der code:

#include <SPI.h>

#define SRAM_DEVICE 53  // SRAM on pin 53 (Atmega 2560)

// 23LC1024 commands

#define SRAM_READ  0b00000011  // 0x03 Read data from memory array beginning at selected address
#define SRAM_WRITE 0b00000010  // 0x02 Write data to memory array beginning at selected address
#define SRAM_RDSR  0b00000101  // 0x05 Read STATUS/MODE register
#define SRAM_WRSR  0b00000001  // 0x01 Write STATUS/MODE register

// operation modes (status register)

#define SRAM_BYTE_MODE 0b00000000  // 0x00 Byte mode (default operation) 
#define SRAM_PAGE_MODE 0b10000000  // 0x80 Page mode
#define SRAM_SEQN_MODE 0b01000000  // 0x40 Sequential mode
#define SRAM_RSVD_MODE 0b11000000  // 0xC0 Reserved
#define SRAM_HOLD_MODE 0b00000001  // 0x01 Set this bit to DISABLE hold mode


byte test = 243;
unsigned long testaddress=112000;
byte outputvar;



void setup (void)
{
  Serial.begin (115200);
  SPI.begin ();    
  SPI.setBitOrder (MSBFIRST );            //MSB first
  SPI.setClockDivider(SPI_CLOCK_DIV2);    //SPI clock 8MHz
  SPI.setDataMode(SPI_MODE3);             // SPI Mode3 (1,1)
  
  pinMode(SRAM_DEVICE, OUTPUT);           //Chipselector Pin
  
  sram_setup (SRAM_DEVICE);
  Serial.println ("end setup\n");
}




void loop (void)
{
 sram_write (SRAM_DEVICE, testaddress, & test);
 sram_read (SRAM_DEVICE, testaddress, & outputvar);
 Serial.println (outputvar);
 
 delay (3000);
}



// setup SRAM device by turning into Byte-Mode
void sram_setup (const byte device)
{
  digitalWrite (device, LOW);   // select device 
  SPI.transfer (SRAM_WRSR); 
  SPI.transfer (SRAM_BYTE_MODE); 
  digitalWrite (device, HIGH);  // deselect device
}  // end of sram_setup



// write bytes from 'data' to device at address 'address'
void sram_write (const byte device, unsigned long address, byte* pdata)
{
  digitalWrite (device, LOW);               // select device
  SPI.transfer (SRAM_WRITE);                // write mode

  //if address higher than 24 Bits, register will rollover                                         
  SPI.transfer (address>>16);               // high-order address byte (23-16) //shift unsined address byte for the first 8Bits
  SPI.transfer (address>>8);                // mid-order address byte (15-8) //shift unsined address byte for the second 8Bits
  SPI.transfer (address);                   // low-order address byte (7-0) //shift unsined address byte for the third 8Bits
  SPI.transfer (*pdata);                    // pdata byte
  digitalWrite (device, HIGH);              // deselect device
  Serial.println ("write");
}  // end of sram_write




// read bytes into 'data' to device from address 'address'
void sram_read (const byte device, unsigned long address, byte* pdata)
{
  digitalWrite (device, LOW);              // select device
  SPI.transfer (SRAM_READ);                // read mode
  
  //if address higher than 24 Bits, register will rollover  
  SPI.transfer (address>>16);               // high-order address byte (23-16) //shift unsined address byte for the first 8Bits
  SPI.transfer (address>>8);                // mid-order address byte (15-8) //shift unsined address byte for the second 8Bits
  SPI.transfer (address);                   // low-order address byte (7-0) //shift unsined address byte for the third 8Bits
  *pdata = SPI.transfer (0);                // read SPI in pdata byte
  digitalWrite (device, HIGH);              // deselect device
  Serial.println ("read");
}  // end of sram_write