Trouble Writing to Parallel SRAM

Go To Last Post
40 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

  I was hoping for a bit of help with a project I'm working on. I'm trying to build a computer based on a 65C02 processor. What I'm planning to do is to use just SRAM in the system and load programs in from an ATMega1284P, which will then provide some simple IO (eventually).

 

I was making some good progress, but then I got stuck with getting the memory to work properly. I've stripped the whole thing back to just the microcontroller and the RAM chip, and for debugging I've cut off half the address bus as per the schematic (SRAM chip is powered, LEDs have current limiting resistors and are connected to ground!).

 

I've connected all 3 of the control signals to the MCU as well because I was struggling with getting the timing to work. The MCU is running at 1MHz. Everything is currently built on breadboards.

parallel memory schematic

 

According to the datasheet for the SRAM, data will be written on the upwards transition of the WE# pin, as long as the address has been valid for 50 nanoseconds, and then the data is valid on the data bus for 25 nanoseconds.

 

I have created a function to write a byte to an address:

 

void write_byte(uint8_t addr, uint8_t data) {
    PORTB = 0b00001101; // WE off, OE off, CS off

    DDRC = 0xff;    // Set data bus for output

    PORTA = addr;   // Set address on address bus
    PORTC = data;   // Set data on data bus
    PORTB = 0b00000100; // pulse WE
    for (uint8_t i=0;i<50;i++) // I know this isn't really 50ns, but it shouldn't matter?
        __asm("nop");       // 1 cycle (1ns?)
    PORTB = 0b00001101; // Set everything back off
}

I've then written some very simple code to load RAM with some values, and then read them back and display them on the LEDs:

 

    for(uint8_t a=0 ; a<255 ; a++) {
        if (a%2) {
            write_byte(a, 0xe7);
        }
        else {
            write_byte(a, 0x7e);
        }
    }
    
    ...
    
    uint8_t b = 0;
    for(uint8_t a=0 ; a<255 ; a++) {
        b = read_byte(a);
        PORTD = b;
        delay(10);
        PORTD = 0;
        delay(10);
    }

Unsurprisingly, this doesn't work. The first 20 or so bytes appear to be written correctly, along with quite a few others along the way, but there's a lot of random junk dumped in the RAM.

 

As ever, I'm doing something stupid and I'm out of my depth. I'd gotten further than this and had the 65C02 hooked up and the 1284P was writing a small program which the 65C02 was happily executing, but it couldn't write anything to the RAM reliably.

 

I stripped it all back and discovered that my write function does not work as I hoped.

 

I would appreciated any help anyone might be able to give.

 

Thanks

-Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:

void write_byte(uint8_t addr, uint8_t data) {
    PORTB = 0b00001101; // WE off, OE off, CS off

    DDRC = 0xff;    // Set data bus for output

    PORTA = addr;   // Set address on address bus
    PORTC = data;   // Set data on data bus
    PORTB = 0b00000100; // pulse WE
    for (uint8_t i=0;i<50;i++) // I know this isn't really 50ns, but it shouldn't matter?
        __asm("nop");       // 1 cycle (1ns?)
    PORTB = 0b00001101; // Set everything back off
}

 

 

If the uC is running at 1MHz, each instruction time is at least 1us (1000ns).

So you don't need the for-loop delay.

 

You seem to be setting the CE# and WE# signals low and then high at the same time.  Not sure if this is in spec.

Try using multiple steps where only one signal is changed at a time.

 

For example:

void write_byte(uint8_t addr, uint8_t data) {
    PORTB = 0b00001101; // WE off, OE off, CS off

    DDRC = 0xff;    // Set data bus for output

    PORTA = addr;   // Set address on address bus
    PORTC = data;   // Set data on data bus
    PORTB = 0b00000101; // CS low
    PORTB = 0b00000100; // WE low
    PORTB = 0b00000101; // WE high
    PORTB = 0b00001101; // CS high
}

 

You will want to do something similar for the read byte function.

 

Last Edited: Sun. Apr 12, 2020 - 08:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chuck99 wrote:

If the uC is running at 1MHz, each instruction time is at least 1us (1000ns).

So you don't need the for-loop delay.

 

Ah, oops. Math ;)

 

Chuck99 wrote:

You seem to be setting the CE# and WE# signals low and then high at the same time.  Not sure if this is in spec.

Try using multiple steps where only one signal is changed at a time.

 

I've tried quite a few different permutations of setting these in different orders. The behaviour changes a bit, but it doesn't 'work' :(

Last Edited: Sun. Apr 12, 2020 - 09:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Put a ‘nop’ after outputting the data and before putting ce and we low. Putting ce and we low at the same time shouldn’t be a problem.
Bypass capacitors are essential on your power rails.

I was recently playing around with a 6502 emulation on a risc-v64 cpu. I doctored the VIC20 roms and did a simple disk interface. At 400MHz, the basic was pretty darn quick.

Last Edited: Sun. Apr 12, 2020 - 09:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When I used those RAM parts, for a write cycle I recall the process we used was:

 

1) make sure the part is not enabled, /write is held HIGH, Output enable is disabled>this is important.  Even though the datasheet timing diagrams show you can do some timing things, why make your life harder<

2) set the address for the location you want to write to.

3) set the data on the data lines.>>Make sure teh Output enable is disabled!!!<<

4) enable the chip

5) enable teh write enable

6) disable the chip

7) disable teh write enable

8) repeat the process for the next byte.

 

Teh datasheet you linked to is rather spartan, but shows soem of what I mention above.  Fairchild semiconductor and SONY made the parts as well so you might want to look for.

 

Good explanation on page one in this datasheet:

https://ecee.colorado.edu/~mcclu...

 

Also, do a search of the forums here.  This has come up several times in teh distant past

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
At 400MHz, the basic was pretty darn quick.

At 400MHZ I would think it would be a lot 'quicker' than PRETTY DARN cheeky

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Silly question - why do you think the write is not working? Could it be the fault is in the read? The common trap is you need to wait one clock before reading the port pins due to the synchroniser hardware.
Just to re-iterate bypass caps. Whilst the ram chip is ‘low power’, when you activate ce, the power consumption jumps. These are fast cmos parts, so power bypassing is critical.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Silly question - why do you think the write is not working? Could it be the fault is in the read? The common trap is you need to wait one clock before reading the port pins due to the synchroniser hardware. Just to re-iterate bypass caps. Whilst the ram chip is ‘low power’, when you activate ce, the power consumption jumps. These are fast cmos parts, so power bypassing is critical.

 

Not a silly question at all - I can't tell for sure which end the error is with what I have set up. As far as I *can* tell, the 'random' noise I get seems to be the same each cycle through memory (I read the RAM out in a loop), which suggests that it's reading the junk stored, rather than making mistakes in the read. It seems to have a 'pattern' in certain sections of RAM, I guess without writing out all 255 values a few times over, I can't be certain it isn't even a bad IC!

 

I have bypass caps on both ICs.

 

I've added NOPs between setting the PORT values and changing the enable logic and it hasn't made much difference. I tried a slightly larger cap for the RAM IC too but that hasn't helped. I thought this would be a lot easier - all the research I did for the 65C02 end makes it look like I can just hook the lines up and it'll all work. I thought getting the 1284P to drive it would be just as easy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Show us the rest of your code. There may be more than one problem

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A good test would be to do a data increment I. Your loop to read back. Meaning, start at address 0, and put a 0x01 in it. Then increment the address, and increment the 0x01 to 0x02 and store it....rinse and repeat for say 24 bytes and then read back to led's with a one second delay between accesses so you can see the led illuminations.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Show us the rest of your code. There may be more than one problem

 

Here's the whole thing:

 

#include <avr/io.h>

#define F_CPU 1000000
#define ever ;;

void delay(uint16_t t);
void rest();
void write_byte(uint8_t addr, uint8_t data);
uint8_t read_byte(uint8_t addr);


void delay(uint16_t t) {
    for ( ; t>0 ; t--) {
        for (uint16_t i=0;i<1000;i++)
            __asm("nop");
    }
}

void write_byte(uint8_t addr, uint8_t data) {
    PORTB = 0b00001101;

    DDRC = 0xff;

    PORTA = addr;
    PORTC = data;
    __asm("nop");
    PORTB = 0b00000101; // CS low
    PORTB = 0b00000100; // WE low
    PORTB = 0b00001100; // CS high
    PORTB = 0b00001101; // WE high
}

uint8_t read_byte(uint8_t addr) {

    PORTB = 0b00001101;

    DDRC = 0x00;
    PORTA = addr;


    PORTB = 0b00000101; // CS low
    PORTB = 0b00000001; // OE low
    __asm("nop");
    uint8_t d = PINC;

    PORTB = 0b00000101; // OE high
    PORTB = 0b00001101; // CS high

    return d;
}

int main (void)
{
    DDRA = 0xff;
    DDRC = 0xff;
    DDRD = 0xff;

    DDRB = 0b00001101;

    // Write disable
    // Output Disable
    // Chip Disable
    PORTB = 0b00001101;


    for(uint8_t a=0 ; a<255 ; a++) {
        if (a%2) {
            write_byte(a, 0x00);
        }
        else {
            write_byte(a, 0x00);
        }
    }

    PORTD = 0xff;
    delay(50);

    for(ever)
    {
        for(uint8_t a=223 ; a<255 ; a++) {
            PORTD = read_byte(a);
            delay(1550);
            PORTD = 0xff;
            delay(50);
        }

        PORTD = 0xff;
        delay(200);
    }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
A good test would be to do a data increment I. Your loop to read back. Meaning, start at address 0, and put a 0x01 in it. Then increment the address, and increment the 0x01 to 0x02 and store it....rinse and repeat for say 24 bytes and then read back to led's with a one second delay between accesses so you can see the led illuminations. Jim

 

I did do that, it's mostly OK, but there are a few bits of garbage in some parts.

 

So. What I just sat and did was:

 

1. Watched the loop and noticed that there's a chunk of *bad* towards the end of RAM (I put a differently timed 0xff on the output so I could see where I was).

 

2. Filled the RAM with 0x00

 

3. Changed the read loop so it's *really* slow, but started at address 223

 

4. Wrote down the *actual* values I read out

 

5. Watched the loop again to see if it was the same garbage data (it was).

 

6, Pulled the power and waited a couple of minutes

 

7. Ran it again

 

8. SAME WRONG DATA

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code looks ok, how about your hardware? Picture?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
The code looks ok, how about your hardware? Picture?

 

ignore the extra chips, they're not in use in this version! Powered at 5v from my ISP.

 

parallel memory breadboard

Last Edited: Sun. Apr 12, 2020 - 10:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Picture is a bit dark. I think you need some better debugging tools. I’d suggest getting a serial link happening. A cheapy saleaea logic clone logic analyser is also suggested. Proto boards are notorious for being unreliable,but atomic zombie does some extensive work with them.

Last Edited: Sun. Apr 12, 2020 - 10:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Picture is a bit dark. I think you need some better debugging tools. I’d suggest getting a serial link happening. A cheapy saleaea logic clone logic analyser is also suggested. Proto boards are notorious for being unreliable,but atomic zombie does some extensive work with them.

 

Sorry, I've edited the post and changed it for a slightly better one.

 

Yeah, I'm not a fan of breadboards either, but I wanted to make sure I could actually get *something* working before I splashed out on making a PCB for it.

 

Logic Analyser is on my list of things to get one day, but I'm not entirely sure I'd know what to do with one if I got one!

 

Thanks for looking.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still a bit dark - needs some flash methinks or better lighting.

 

Rather than make a pcb - you should try some dot board (perf board and other names), some ic sockets and some fine gauge magnet wire and hand wire stuff up. Involves soldering. I used to make all my prototypes and one-offs that way. Some of my boards are still working 40 years later!

 

As for a logic analyser, you'd be surprised how much you'd use it. Apart from decoding i2c,spi and uart data, you'd be able to measure your timing in a jiffy. These things are only USD$10 or so. Having one won't break the bank. I have a number of them as well as a 'real' Tektronix analyser. 

 

If your 100nF bypass capacitors have long enough legs, place them across the ic. 

Last Edited: Sun. Apr 12, 2020 - 11:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

If your 100nF bypass capacitors have long enough legs, place them across the ic. 

 

I'd like to see a lot more capacitors myself.  Better lots of little ones than a few big ones,  but I'd stick a big one (electrolytic, 220uF or so) in one corner or two.  Also use the + power rails on your breadboard - it looks like you're using only the - rails.  This also makes it much easier to stick little capacitors here and there... 

 

Also check just how much current your ISP is providing.  A separate 5V supply might be in order.  If you have an analog meter, they'll show sudden drops on the 5V line much faster than digital ones.

 

S.

 

PS - Your schematic doesn't actually show +5 on the SRAM Vcc, but I imagine it's in there (without it might still work through protection diodes, but not work well).  Use nice short wires directly to the rails, and make sure your capacitors have as short as possible loop runs (from the chip Vcc pin to the cap to the chip GND pin).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your schematic doesn't show a GND connection to pin 31.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:
I'd like to see a lot more capacitors myself.  Better lots of little ones than a few big ones,  but I'd stick a big one (electrolytic, 220uF or so) in one corner or two.  Also use the + power rails on your breadboard - it looks like you're using only the - rails.  This also makes it much easier to stick little capacitors here and there... 

 

OK, I've sprinkled in some extra capacitors (I am using both power rails, the photo looked a lot worse off my laptop! sorry, added a much better one below).

 

I'm also powering it from a 5V 1A external supply (plugged into the middle rail on the left, ISP power is disconnected).

 

I'm still getting the same problem - *most* addresses read and write as expected, but a handful do not. I did try switching some of the upper address lines between 0 and +5 whilst it was running and this didn't seem to have any effect, which suggests, well, I really don't know what it suggest or what to do next.

 

I'll try getting a serial port going I think.

 

parallel memory breadboard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:

Your schematic doesn't show a GND connection to pin 31.

 

it is, I think I used the wrong symbol in the schematic and didn't notice it missing. I drew the schematic from what I made on the breadboard though, the power and grounds are all connected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did another test thing before I start yanking wires.

 

I changed the write loop to write the numbers 0 - 255 in the corresponding memory addresses. Then read it back one at a time.

 

0, 1, 2, 3 all work consistently.

4 consistently reads back as 68 instead of 4, each of the next positions 5, 6, & 7 have the 64s bit set, then 8 is ok again.

 

I changed the code and added a separate write to address 4 with the value 4, that *works*, if I do the same for 5, 6, & 7 they work fine too.

 

Watching some more of the pattern, a lot of the values that are wrong appear to be when the 4s bit is set - after 8 is 'ok', 9, 10, & 11 are ok, but 12 has the 64s bit set too.

 

I go back and add a line to write 12 to 12 after the loop and that works fine.

 

So I change the write loop to write 0 to all addresses, everything is fine until it gets to 33, 34 & 35 which have random (consistent) values in them, and then so on up the addresses.

 

The thing that bothers me most is that the errors are consistent, I can reset the 1284P, I can pull the power and wait, but I'll still get the same patterns of errors. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What value are the resistors on the leds?

Try putting the 5V and 0V power wires from one side of the chip to the other. Your current setup has a rather torturous path for the currents to flow - especially with the leds in the mix.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

What value are the resistors on the leds?

Try putting the 5V and 0V power wires from one side of the chip to the other. Your current setup has a rather torturous path for the currents to flow - especially with the leds in the mix.

 

Resistors are 220 Ohm. I'm going to rewire it a bit more simply. Ben Eater never has this trouble in his YouTube videos with these things :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

220Ohms seems a bit low in value. That will give you a wide variation in current consumption. I would’ve gone for 1k, but the leds in that bar graph are probably crappy and require 20mA.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One thing I'm surprised nobody has commented :) (I think)

 

Until it works keep CE low at all time ! (when this is the only chip it's only use is to save power).

Use OE for read 

And WE for write

 

Add

Before the STK500 came out I had a STK200 (I think or a even older board, but for sure a Atmel board), and on that there was a RAM socket and I had a 8515 running with it without any problems, so perhaps take a look there.

  

Last Edited: Mon. Apr 13, 2020 - 11:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:

 

I'm going to rewire it a bit more simply.

 

So, I rewired the whole thing, took out the LEDs and replaced them with a serial connection.

 

It works flawlessly, whatever I write to the SRAM, I can read it back exactly as I expect. Immensely frustrating. It even seems to work fine without any decoupling capacitors (I put them back in though, cos why tempt the electronics gods).

 

Thank you folks for pushing me towards finding a solution. I'm not sure that I understand why it wasn't working though? Were the LEDs the issue? they weren't actually switching on until *after* I'd written out everything and made the reads, so I don't understand how they would have caused a problem? I've changed all the wires, so I suppose that's another variable? It's a different breadboard too?

 

parallel memory breadboard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Electrolytic caps make poor bypass caps!  Use 100nf!!!

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:
So, I rewired the whole thing, took out the LEDs and replaced them with a serial connection.

MalphasWats wrote:
It works flawlessly,

 

Which makes me think that :

MalphasWats wrote:
I'm also powering it from a 5V 1A external supply

 

Is not as good as its rating.....

 

Great to read that it works!

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Nice it's working ...

But where is JTAG on that MCU , people have been bitten by not disabling that

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

Electrolytic caps make poor bypass caps!  Use 100nf!!!

Jim

 

This is correct, and I should have explained myself more clearly.  Lots of little 100nF caps are essential - a few bigger electrolytics are nice to have.  Maybe this picture will help:

 

Decoupling example

 

Have fun,  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What’s to say that when you turned on an led that it scrambled the ram?

Also note your power distribution - you could possibly drop current across the mega1284 - bad juju. Current flows in a loop - make the loop as small as possible. I’d suggest running the power on pins 30,31 across a he chip. As noted by Scrounge, electros are useless as bypass caps.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Technically, wasn't me, that was Jim (ki0bk), but yes, the idea is firm. 

 

Lots of little 0.1uF caps right around the chips, up close and personal (on big AVRs, I've been known to lay out four - if I really feel like being clever, I put SMT ones on the back directly underneath the chip.  Look at a suggested layout for a big FPGA (and what's already stuck in the plastic itself) if you want to see what the high-dollar professionals do). 

 

A couple big electro caps loitering about in reasonably short range is not a bad thing, especially given a maybe flaky power supply.  S.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It may have been misinterpreted that lots of little electrolytics (22uF or so) are better than a few big ones.  And that's true, to some extent (they are better, for several reasons), but not at digital circuit switching frequencies, and hence decoupling.

 

What I meant by 'lots of little are better than a few big' as far as decoupling is concerned, it's much better to have ten generously scattered 100nF caps than one 1uF cap.  Increasing the value of the decoupling caps can be actively counterproductive, because the improvement in farads comes with worsening qualities in things like inductance and ESR.

 

So use lots of very little (0.1uf!) caps everywhere, and happiness, if not ensured, is more likely.  So there.  cheeky  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bingo600 wrote:

Nice it's working ...

But where is JTAG on that MCU , people have been bitten by not disabling that

 

 

Ha, yeah, I get bitten by JTAGEN every time I plug in a new MCU :) Then I remember and I write the fuses properly and things usually work!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've replaced the electrolytic caps with some ceramic ones. I don't have the right values on hand at the moment though, so I'll have to order some more.

 

Kartman wrote:
What’s to say that when you turned on an led that it scrambled the ram?

 

Ah! I suppose that makes sense. At the risk then of asking too much, what would I need to do so that I could use LEDs in my circuit? I don't really need them now as I have a serial connection to output debugging stuff, but I'd like to have the option later.

 

Is it as simple as shoring up the bypass capacitors with the proper values and placement, changing the resistor values to reduce the current of the LEDs and/or using a better power supply?

 

Kartman wrote:
Also note your power distribution - you could possibly drop current across the mega1284 - bad juju. Current flows in a loop - make the loop as small as possible. I’d suggest running the power on pins 30,31 across a he chip. As noted by Scrounge, electros are useless as bypass caps.

 

I have to be honest (and a little embarrassed) but I'm not sure what you mean with this? Do you mean that I should just have short little jumpers going from Pin 31 to 11 and 30 to 10 directly, rather than via the rails on the breadboard? Is it better practice to only use 1 of the power strips (either top or bottom)? It's all mostly moot because I plan on putting it all on custom PCBs and I'm a lot better at laying those out than breadboards, but I still have a few things I want to get working before I commit fully to what I'm trying to make.

 

Here's the latest version using shift registers for the address bus to free up some IO for later (and USART) :)

 

parallel memory breadboard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:

Which makes me think that :

MalphasWats wrote:
I'm also powering it from a 5V 1A external supply

 

Is not as good as its rating.....

 

Yeah, I'd really like a bench power supply. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ceramic caps will do, and the new layout is MUCH cleaner than the old one.  I like that you left one electrolytic in there - but I'd have left it in the other corner, right beside the power input.  Doesn't matter much.

 

Breadboard power rails are probably as good as you're going to get - just make sure The Loop is short - just hooking the cap up to both rails is not going to do it, because each rail goes all the way down to the bottom hookups and then comes back up again - that's a horribly long loop.  Put some more jumpers in there.

 

As far as LEDs, it seems they were the problem, and your 5V 1A supply might not quite be that.  A seriously larger local cap (think 2,200uF) might help, but it might not.  How far away is it on how thin wires?

 

It's also worth noting that at this time your AVR is really gently loping along at 1MHz.  If you want it to go faster later you'll need a better board.  It's quite possible your AVR was tolerating power brownouts that your SRAM could not.

 

There's ways to run LEDs off of a big cap with an inrush resistor, if you were interested.  Throw them like a solenoid with an outrush, too. 

 

Hope this helps.  S.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:
220 Ohm
At 5V, and a 2.1V LED, that's about 13 mA per LED.  With eight of them, that's 105 mA.  A bit too much.

1.)The sum of all IOL, for ports PB0-PB7, XTAL2, PD0-PD7 should not exceed 100mA.

And without proper bypass, and with a possibly dodgy PSU/layout, that's asking for trouble.  As Kartman says, 1K is plenty.  Will still give you 3mA per LED.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MalphasWats wrote:
I should just have short little jumpers going from Pin 31 to 11 and 30 to 10 directly, rather than via the rails on the breadboard?
 Yes. 

 

Where you see wires, I see resistors and inductors. CMOS circuits add a lot of high frequency noise on their power rails as they basically charge and discharge capacitors - the average current is low, but peak currents are very high. This is in contrast with the 70's TTL circuits that sucked current and NMOS circuits that weren't quite as bad. As per #31 you want the loop for the bypass capacitor short and low inductance so the peak CMOS currents are drawn from the bypass capacitors. SMT ics are preferable due to the smaller size and thus being able to make the loop even smaller. 

 

My guess as to the root cause of your original problem was the power distribution and the current for the leds going via the AVR. How Ben Eater addresses this is that he uses buffer chips from what I can see.Probably some HC574s(octal flip/flops) or suchlike. Minimising currents also helps with power distribution.

 

 

In designing a PCB - power layout is something that many people do very poorly. Here we've seen power done as 0.2mm tracks, no bypass caps and complaints that it doesn't work.  

Avoid having your microcontroller be the meat in a power supply sandwich - don't pass currents across the micro. Things like pullup resistors are ok, but don't have a bank of high brightness leds suck their power via tracks for your micro. Where possible have a continuous ground plane on the solder side of the pcb. Your 0V paths can find a low impedance path back to the power supply.