Pages: [1] 2 3   Go Down
Author Topic: [Solved] Problems accessing parallel SRAM  (Read 7943 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm learning parallel interfacing and I'm using an 8Kx8 SRAM from Cypress (CY7C185) in DIP28 format.
I use 3 74HC595 S/P shift registers, 1 74HC165 P/S shift register and an Arduino Uno.

I used 2 of the 74HC595 s/r to translate the address from serial to parallel, the other 74HC595 to read/write the data through the I/O bus of the RAM and the 74HC165 P/S s/r to convert the read data from parallel to serial.

In attachment you'll find the schematic of my project. The pins on the left are the Arduino pins.

This is my code. It simply tries to write some data into the SRAM and them tries to write the values into the EEPROM of the uC for a further check.
Code:
/* CONNECTION TEST TO A SRAM CHIP OF 8Kx8
USING 2 74595 SHIFT REGISTERS TO MANAGE THE ADDRESS,
1 74595 TO MANAGE THE DATA TO BE READ/WRITTEN INTO THE RAM
AND 1 74165 P/S SHIFT REG. TO READ DATA FROM RAM

*/
#include <EEPROM.h>

// Connecting the pins
//1st and 2nd 595
#define data1pin 0 //pin DS
#define latch1pin 1 //pin ST_CP
#define clock1pin 2 //pin SH_CP

//3rd chip 595
#define data2pin 8 //pin DS
#define latch2pin 9 //pin ST_CP
#define clock2pin 10 //pin SH_CP

//this is common for all the 3 595s
#define master_reset 3 //pin MR/ of the 3 chips

//SRAM Chip
#define ram_we 4 //pin WE/
#define ram_ce2 5 //pin CE2
#define ram_oe 6 //pin OE/
#define ram_ce1 7 //pin CE1/

//chip 165
#define clock3pin 11 //pin CP
#define set_load 12 //pin PL/
#define load_data 13 //pin Q7

/* SRAM
TO WRITE:
CE1/ -> LOW
WE/ -> LOW
CE2 -> HIGH
OE/ -> LOW

TO READ:
WE/ -> HIGH
CE1/ -> LOW
OE/ -> LOW
CE2 -> HIGH
*/

#define READ 2 //RAM status: prepare it for reading
#define WRITE 1 //RAM status: prepare it for writing
#define DISABLE 0 //RAM status: disable it

void clear_shift_registers() {
    //cleans the internal registers of the 595 s/r
    //avoiding old datas to be read instead of new ones
    digitalWrite(master_reset, LOW);
    delay(50);
    digitalWrite(master_reset, HIGH);
}

void set_ram(byte stato) {
    
    switch (stato) {
        case DISABLE:
            digitalWrite(ram_ce1, HIGH);
            digitalWrite(ram_oe, HIGH);
            digitalWrite(ram_ce2, LOW);
            digitalWrite(ram_we, HIGH);
            break;
        case WRITE:
            digitalWrite(ram_ce1, LOW);
            digitalWrite(ram_ce2, HIGH);
            digitalWrite(ram_we, LOW);
            digitalWrite(ram_oe, LOW);
            break;
        case READ:
            digitalWrite(ram_ce1, LOW);
            digitalWrite(ram_ce2, HIGH);
            digitalWrite(ram_oe, LOW);
            digitalWrite(ram_we, HIGH);
            break;
    }
}

void setup() {
    //initial pin setup
    //
    pinMode(master_reset, OUTPUT);
    //pin of the shift registers 1, 2 and 3: OUTPUT
    pinMode(latch1pin, OUTPUT);
    pinMode(clock1pin, OUTPUT);
    pinMode(data1pin, OUTPUT);
    pinMode(data2pin, OUTPUT);
    pinMode(clock2pin, OUTPUT);
    pinMode(latch2pin, OUTPUT);
    
    //RAM pins: OUTPUT
    pinMode(ram_we, OUTPUT);
    pinMode(ram_ce1, OUTPUT);
    pinMode(ram_ce2, OUTPUT);
    pinMode(ram_oe, OUTPUT);
    
    //S/r 165
    pinMode(clock3pin, OUTPUT);
    pinMode(set_load, OUTPUT);
    pinMode(load_data, INPUT);  
    
    //initialize
    clear_shift_registers();
    
}

void loop() {
unsigned int indirizzo; //the address to be used
byte valore = 0; //the value to be used
int eeprom_pointer = 0; //pointer to EEPROM location

    // clear 10 locations in the SRAM and then write a sequence of numbers
    for (indirizzo = 0; indirizzo <10; indirizzo++) {
        scrivi_ram(indirizzo,valore);
        valore += 3;
        EEPROM.write(eeprom_pointer, valore);
        eeprom_pointer++;
        delay(10);
    }
    delay(1000);
    
    //read the first 10 bytes and then write them into the uC EEPROM
    for (indirizzo = 10; indirizzo < 20; indirizzo++) {
        valore = leggi_ram(indirizzo);
        EEPROM.write(eeprom_pointer, valore);
        delay(10);
    }
    delay(5000);
    //delay
    
}

void scrivi_ram(unsigned int indirizzo, byte valore) {
    byte hbyte, lbyte;
    
    //write the address into the shift registers 1 and 2
    clear_shift_registers();
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    hbyte = highByte(indirizzo);
    lbyte = lowByte(indirizzo);
    shiftOut(data1pin, clock1pin, MSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, MSBFIRST, lbyte);
    //write the value into the 3rd s/r
    shiftOut(data2pin, clock2pin, MSBFIRST, valore);
    
    //write the value into the RAM
    set_ram(WRITE);
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    delay(10);
    
    //disable all the chips
    set_ram(DISABLE);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
}

byte leggi_ram(unsigned int indirizzo) {
byte valore, hbyte, lbyte;
    
    //read the content of the byte "indirizzo"
    //write the address
    clear_shift_registers();
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    hbyte = highByte(indirizzo);
    lbyte = lowByte(indirizzo);
    shiftOut(data1pin, clock1pin, MSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, MSBFIRST, lbyte);
    
    //wake up the SRAM and set it for reading
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    
    set_ram(READ);
    digitalWrite(clock3pin, HIGH);
    digitalWrite(set_load, LOW);
    delayMicroseconds(5);
    digitalWrite(set_load, HIGH);
    set_ram(DISABLE);
    shiftIn(load_data, clock3pin, valore);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    return valore;
    
}

But reading the EEPROM I only get the values written in the first 10 bytes during the first pass, when my code tries to write to the SRAM, but I don't find any value in the last 10 bytes (I only find the default values, $FF).

I cannot understand how to pilot this device.

EDIT: I uploaded an english version of the code, to better understand my ideas


* sram.jpg (75.35 KB, 957x673 - viewed 111 times.)
« Last Edit: February 02, 2011, 06:32:38 pm by leo72 » Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 533
Posts: 26951
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why do you have OE low when you trying to write the SRAM? I think this would interfere.
The Datasheet shows OE High during writes to the part.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for the suggestion. I'll try it.

EDIT:
didn't solve my problem....  smiley-confuse
« Last Edit: February 01, 2011, 03:40:30 am by leo72 » Logged


Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 610
Posts: 49071
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pin 13 has a resistor to go with the on-board LED. Perhaps using a different pin for the load_data pin would be a good idea, since that pin needs to be an INPUT pin.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33961
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You are using D0 and D1 (or Pin 0 and Pin 1) on the arduino, these are best left for the serial communications. Use pins 14 and 15 (analogue pins 0 and 1) instead.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Still not working... I changed a couple of pins, putting D0->A0, D1->A1, D12->A2 and D13->D12 but still not work.
The analog pins can be both input and output, isn't it?
I use to configure them as follow:

#define example_pin A0
...
pinMode(example_pin, OUTPUT);

Is it correct?

This is the code I'm testing right now:
Code:
/* CONNECTION TEST TO A SRAM CHIP OF 8Kx8
USING 2 74595 SHIFT REGISTERS TO MANAGE THE ADDRESS,
1 74595 TO MANAGE THE DATA TO BE READ/WRITTEN INTO THE RAM
AND 1 74165 P/S SHIFT REG. TO READ DATA FROM RAM

*/
#include <EEPROM.h>

// Connecting the pins
//1st and 2nd 595
#define data1pin A0 //pin DS
#define latch1pin A1 //pin ST_CP
#define clock1pin 2 //pin SH_CP

//3rd chip 595
#define data2pin 7 //pin DS
#define latch2pin 8 //pin ST_CP
#define clock2pin 9 //pin SH_CP
#define outputEnable 10 //pin OE/

//SRAM Chip
#define ram_we 3 //pin WE/
#define ram_ce2 4 //pin CE2
#define ram_oe 5 //pin OE/
#define ram_ce1 6 //pin CE1/

//chip 165
#define clock3pin 11 //pin CP
#define set_load 12 //pin PL/
#define load_data A2 //pin Q7

/* SRAM
TO WRITE:
CE1/ -> LOW
WE/ -> LOW
CE2 -> HIGH
OE/ -> LOW

TO READ:
WE/ -> HIGH
CE1/ -> LOW
OE/ -> LOW
CE2 -> HIGH
*/

#define READ 2 //RAM status: prepare it for reading
#define WRITE 1 //RAM status: prepare it for writing
#define DISABLE 0 //RAM status: disable it

void set_ram(byte stato) {
   
    switch (stato) {
        case DISABLE:
            digitalWrite(ram_ce1, HIGH);
            digitalWrite(ram_oe, HIGH);
            digitalWrite(ram_ce2, LOW);
            digitalWrite(ram_we, HIGH);
            break;
        case WRITE:
            digitalWrite(ram_ce1, LOW);
            digitalWrite(ram_ce2, HIGH);
            digitalWrite(ram_we, LOW);
            digitalWrite(ram_oe, HIGH);
            break;
        case READ:
            digitalWrite(ram_ce1, LOW);
            digitalWrite(ram_ce2, HIGH);
            digitalWrite(ram_oe, LOW);
            digitalWrite(ram_we, HIGH);
            break;
    }
}

void setup() {
    //initial pin setup
    //
    //pinMode(master_reset, OUTPUT);
    //pin of the shift registers 1, 2 and 3: OUTPUT
    pinMode(latch1pin, OUTPUT);
    pinMode(clock1pin, OUTPUT);
    pinMode(data1pin, OUTPUT);
    pinMode(data2pin, OUTPUT);
    pinMode(clock2pin, OUTPUT);
    pinMode(latch2pin, OUTPUT);
   
    //RAM pins: OUTPUT
    pinMode(ram_we, OUTPUT);
    pinMode(ram_ce1, OUTPUT);
    pinMode(ram_ce2, OUTPUT);
    pinMode(ram_oe, OUTPUT);
   
    //S/r 165
    pinMode(clock3pin, OUTPUT);
    pinMode(set_load, OUTPUT);
    pinMode(load_data, INPUT); 
    pinMode(outputEnable, OUTPUT);
   
    //initialize
   
}

void loop() {
unsigned int indirizzo; //the address to be used
byte valore = 0; //the value to be used

    // clear 10 locations in the SRAM and then write a sequence of numbers
    for (indirizzo = 0; indirizzo <10; indirizzo++) {
        scrivi_ram(indirizzo,valore);
        valore += 3;
        EEPROM.write(indirizzo, valore);
        delay(10);
    }
    delay(1000);
   
    //read the first 10 bytes and then write them into the uC EEPROM
    for (indirizzo = 0; indirizzo < 10; indirizzo++) {
        valore = leggi_ram(indirizzo);
        EEPROM.write(indirizzo+10, valore);
        delay(10);
    }
    delay(5000);
    //delay
   
}

void scrivi_ram(unsigned int indirizzo, byte valore) {
    byte hbyte, lbyte;
   
    digitalWrite(set_load, HIGH); // put the 165 pins in H.I. to prevent short circuits on the data bus
    digitalWrite(outputEnable, LOW); //wake up the 3rd 595
    //write the address into the shift registers 1 and 2
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(clock1pin, LOW);
    digitalWrite(clock2pin, LOW);
    hbyte = highByte(indirizzo);
    lbyte = lowByte(indirizzo);
    shiftOut(data1pin, clock1pin, LSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, LSBFIRST, lbyte);
    //write the value into the 3rd s/r
    shiftOut(data2pin, clock2pin, LSBFIRST, valore);
   
    //write the value into the RAM
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    set_ram(WRITE);
    delay(10);
   
    //disable all the chips
    set_ram(DISABLE);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(outputEnable, HIGH);
}

byte leggi_ram(unsigned int indirizzo) {
byte valore, hbyte, lbyte;
   
    //read the content of the byte "indirizzo"
    //write the address
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(outputEnable, HIGH); //deselect the 3rd 595, so its output pins go into H.I. state
    hbyte = highByte(indirizzo);
    lbyte = lowByte(indirizzo);
    shiftOut(data1pin, clock1pin, LSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, LSBFIRST, lbyte);
   
    //wake up the SRAM and set it for reading
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);

    set_ram(READ);
    digitalWrite(clock3pin, HIGH);
    digitalWrite(set_load, LOW);
    delayMicroseconds(50);
    digitalWrite(set_load, HIGH);
    set_ram(DISABLE);
    shiftIn(load_data, clock3pin, valore);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    return valore;
   
}
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33961
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
#define example_pin A0
...
pinMode(example_pin, OUTPUT);

Is it correct?

No

#define example_pin 14
...
pinMode(example_pin, OUTPUT);

Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah... but in this thread you said the opposite thing  smiley-lol:

Quote
Under version 20 and beyond A0 is a predefined constant.
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33961
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes but it is predefined as zero not as 14 which is what you want for using an analogue pin as a digital one.
So
val = analogRead(A0); // is fine but
val = digitalRead(A0); is the same as val = digitalRead(0);
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nothing changed.... I'm bored...  smiley-roll uff...

I'm starting to think that what I want to do is the classic "mission impossible".... is it possible to drive a parallel RAM with the peripherical chips I chose?
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33961
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
is it possible to drive a parallel RAM with the peripherical chips I chose?
Yes it is. Do you have a scope so you can see if you are waggling the wires correctly?
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

No, I don't.

I think I will have di de-wire all the chips and start wiring up again from scratch.
One thing that I noticed is that if I disconnect the Vcc/GND wires from the Arduino board, the power LED that I've put on the breadboard still has a faint light, as in the circuit some current is still running, maybe from the output pins of the Arduino.... I don't know if it's normal...

I know that putting a pin of the Arduino in OUTPUT state should generate a low current: maybe with 14 pins connected to the circuit some sort of parasite current is still running through the wires... don't know...  smiley-kitty

This night I will have some time to check the circuit. Stay tuned...  smiley-wink
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 619
Posts: 33961
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Don't forget to include decoupling capacitors, it won't work without them.

Quote
One thing that I noticed is that if I disconnect the Vcc/GND wires from the Arduino board, the power LED that I've put on the breadboard still has a faint light,
This implies you have disconnected power and ground but left the signal wires going into the chips. That is a good way to kill them. Never put a signal into an unpowerd chip.
Logged

Auburn, CA, USA
Offline Offline
Newbie
*
Karma: 3
Posts: 20
Arduino pebbles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's entirely possible to drive parallel chips with shift registers, but on MCUs with SPI/I2C hardware (or software) it's not as practical since SRAM chips are also manufactured with built-in SPI/I2C hardware.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This implies you have disconnected power and ground but left the signal wires going into the chips. That is a good way to kill them. Never put a signal into an unpowerd chip.
smiley-roll-blue
Logged


Pages: [1] 2 3   Go Up
Jump to: