Pages: 1 [2] 3   Go Down
Author Topic: [Solved] Problems accessing parallel SRAM  (Read 7622 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 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.

This is a test. I want to learn how to do that because another project of mine is to build a rudimental and simple microcomputer using a 8-bit CPU from the 70s/80s, like a Z80 or a 6502.
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

Please explain how this part works:
Code:
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;
    }
}

I think your sequencing may be a  little off. Hard to tell without a multichannel scope, so lets simplify.

For reading the SRAM, you can set the control lines, CE1/, OE/ low; CE2, WE/ high, then apply address and you will get data out. This is Read Cycle 1, the data will come out after the address settles, the control lines can be static.
For writing, you want to control it so that only 1 control line determines when the write actually occurs;
I would set CE1/ low, CE2 high, OE/ low, and then pulse WE/ low after the address & data are setup. 

So, Keep it simple.
As you are accessing only 1 chip, make your steady state this: keep CE1/ low, CE2 high, OE/ high, and WE/ high.
When you read, setup the address, take OE/ low, capture the output with the 74165 latch (or clock) pin, and bring OE/ back high.
When you write, setup the address and data, take the WE/ pin low and then back high.
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I based that part of code on info taken from the datasheet of the RAM chip (this one, at the end of the page). In it, it  is said that to write or read we have to put some pin LOW and/or HIGH, so using those info, I wrote that part of code.
So, before to do any operation, I call that routine to set the proper pins at the proper state.


I will try to simplify my code before to re-wire my circuit  smiley-wink
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

Ok, I am an EE that used to design these parts in.
I read the data sheet  before I made my suggestion.
If you read the timing diagrams, you will see that it is the combination of pins that performs the write, with the simplest combination being to make 1 pin change to end the read or write action end.
So keep it simple - do not change several control pins at once, only pulse 1 pin low after the rest are settled is all that is needed.
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've tried this way but it didn't work....
This is the part of the code that perform the write & read cicles:
Code:
v
void write_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);
    //set the address and data "visibile" on the busses
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    //write to RAM
    digitalWrite(ram_we, LOW);
    delay(1);
    digitalWrite(ram_we, HIGH);
   
    //disable all the chips
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(outputEnable, HIGH);
}

byte read_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);
   
    //set the address "visible" on the bus
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    //prepare the 165
    digitalWrite(clock3pin, HIGH);
    digitalWrite(set_load, LOW);
    //read from RAM
    digitalWrite(ram_oe, LOW);
    delay(1);
    digitalWrite(ram_oe, HIGH);
    //load the data from the 165
    digitalWrite(set_load, HIGH);
    shiftIn(load_data, clock3pin, valore);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    return valore;
   
}
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

You have the chip selects set Lo & Hi elsewhere?
You don't need the 1mS delay - the part only needs nanoseconds to do the write, so just the consecutive write low/write high will do it.
In this part
Code:
    //read from RAM
    digitalWrite(ram_oe, LOW);
    delay(1); // <- get rid of this
    digitalWrite(ram_oe, HIGH);  // <- this has to go after the 165 latch/clock signal.
    //load the data from the 165
    digitalWrite(set_load, HIGH);
    shiftIn(load_data, clock3pin, valore);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    return valore;
the ram OE needs to stay low until the 165 has the data clocked/latched in, otherwise you just read whatever is floating on the output-disabled pins.
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nothing.... I'll check all the wires and then I'll try tomorrow using some LEDs to start testing the output from 595 and 165 to find the wrong thing in my circuit: if the code is correct, then it's an hardware issue.
Logged


nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8471
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
build a rudimental and simple microcomputer using a 8-bit CPU from the 70s/80s, like a Z80 or a 6502.
Way to go  smiley

Just the other day I was thinking of doing the same thing, God knows why, nostalgia I suppose as I cut my teeth on Z80s and it would be a fun project. You can still buy all the chips CPU, SIO, DART, PIO, CTC etc and they still market the Microprofessor development board.

Whether or not getting this working will be much help with getting a Z80 system running I'm not sure, apart from just gaining general digital experience.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
God Member
*****
Karma: 32
Posts: 507
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The 595 on the data bus looks like it has its output enable hardwired low, therefore it will always be in output mode. So when you are trying to read from the RAM, both the RAM and the 595 will be fighting over the bus - they will both be trying to output their data onto the bus at the same time (causing a lot of short-circuits in the process).

You want the data bus 595 to have its outputs disabled when doing a read. Sometimes it also works if you connect up the two fighting buses with resistors instead of wires (thus controlling which one dominates over the other - this trick is used in some 80s computers)
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

Yes, that would be a problem! That pin should be connected to the WE/ line of the SRAM. The write will end with WE going high, and there is 0nS hold time required for the data.
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just the other day I was thinking of doing the same thing, God knows why, nostalgia I suppose as I cut my teeth on Z80s and it would be a fun project. You can still buy all the chips CPU, SIO, DART, PIO, CTC etc and they still market the Microprofessor development board.

Whether or not getting this working will be much help with getting a Z80 system running I'm not sure, apart from just gaining general digital experience.

My first computer was a C16, with which I learned programming in BASIC and Assembly  smiley-lol
In my wallet I've already 2 Z80B and 1 6502  smiley-mr-green

I know it will VERY difficult for me, because I only have very basic electronic skills but, as you said, I want to try this thing to make experience.

@stimmer & CrossRoads:
interesting suggestion. I'll check the circuit today (when my brain will stop explodind into may head, as I have a cold and a cough that are killing me...)
Logged


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

Hello again.. the neverending story still continues...  smiley-eek-blue

I checked the wiring 3 or 4 times... My eyes are burned.... but my circuit still doesn't work.
The latest schematic is at the bottom, belove is the code:
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 2 //pin DS
#define latch1pin 3 //pin ST_CP
#define clock1pin 4 //pin SH_CP

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

//SRAM Chip
#define ram_we 5 //pin WE/ + 3rd 595 OE/
#define ram_oe 6 //pin OE/

//chip 165
#define load_data 11 //pin CP
#define set_load 12 //pin PL/
#define clock_pin 8 //pin Q7

void setup() {
    //initial pin setup
 
    //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_oe, OUTPUT);
   
    //S/r 165
    pinMode(clock_pin, OUTPUT);
    pinMode(set_load, OUTPUT);
    pinMode(load_data, INPUT); 
   
    //initialize ram
    digitalWrite(ram_oe, HIGH);
    digitalWrite(ram_we, HIGH);
   
    //set D13 for LED flashes
    pinMode(13, OUTPUT);
}

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

    // clear 10 locations in the SRAM and then write a sequence of numbers
    for (mem_address = 0; mem_address <10; mem_address++) {
        write_ram(mem_address, value);
        value += 3;
        EEPROM.write(mem_address, value);
        delay(10);
    }
    delay(500);
   
    //read the first 10 bytes and then write them into the uC EEPROM
    for (mem_address = 0; mem_address < 10; mem_address++) {
        value = read_ram(mem_address);
        EEPROM.write(mem_address+10, value);
        delay(10);
    }
    digitalWrite(13, HIGH);
    delay(3000);
    digitalWrite(13, LOW);
   
}

void write_ram(unsigned int mem_address, byte value) {
    byte hbyte, lbyte;
   
    digitalWrite(set_load, HIGH); // put the 165 pins in H.I. to prevent short circuits on the data bus
    //write the address into the shift registers 1 and 2
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(clock1pin, LOW);
    digitalWrite(clock2pin, LOW);
    hbyte = highByte(mem_address);
    lbyte = lowByte(mem_address);
    shiftOut(data1pin, clock1pin, MSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, MSBFIRST, lbyte);
    //write the value into the 3rd s/r
    shiftOut(data2pin, clock2pin, MSBFIRST, value);
    //set the address and data "visibile" on the busses
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    //write to RAM
    digitalWrite(ram_we, LOW);
    digitalWrite(ram_we, HIGH);
   
    //disable all the chips
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
}

byte read_ram(unsigned int mem_address) {
byte value, hbyte, lbyte;
   
    //read the content of the byte "indirizzo"
    //write the address
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    digitalWrite(ram_we, HIGH); //disable the 3rd 595 and tell the RAM not to write in itself
    hbyte = highByte(mem_address);
    lbyte = lowByte(mem_address);
    shiftOut(data1pin, clock1pin, MSBFIRST, hbyte);
    shiftOut(data1pin, clock1pin, MSBFIRST, lbyte);
   
    //set the address "visible" on the bus
    digitalWrite(latch1pin, HIGH);
    digitalWrite(latch2pin, HIGH);
    //prepare the 165
    digitalWrite(clock_pin, HIGH);
    digitalWrite(set_load, LOW);
    //read from RAM
    digitalWrite(ram_oe, LOW);
    //load the data from the 165
    digitalWrite(set_load, HIGH);
    digitalWrite(ram_oe, HIGH);
    shiftIn(load_data, clock_pin, value);
    digitalWrite(latch1pin, LOW);
    digitalWrite(latch2pin, LOW);
    return value;
   
}

I simplified the schematic as much as I could, but I still am not able to read (or maybe write) any byte.

If someone can tell me that both seem OK, then I de-wire everything and try using LEDs, my last test.


* schematic2.jpg (77.38 KB, 788x394 - viewed 46 times.)
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

U2, disconnect the 3 outputs QF, QG, QH, from ground, that can't be good for the chip.
U3, you have SERCLR tied to ground,that will keep any data from being shifted in, you will only put 0s out for data.

I think you're getting close!
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: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

U2:pins disconnected.
U3:SERCLR is already connected to Vcc. I made a mistake drawing the schematic.

Result: nothing...

Uhm.. Tomorrow I will try using LEDs.... maybe I've burned some chip trying and re-trying during this days.... don't know...

Question: I'm using the Arduino to supply the power at the circuit. Is its current enough?
Logged


Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 518
Posts: 26359
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

Well, the SRAM needs 140mA, the HC parts use very little, 50-60mA for the Arduino. What do you have for a power source?
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.

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